C# 多线程的问题

来源:互联网 发布:网络通信sig加密 编辑:程序博客网 时间:2024/05/23 01:59

1.invoke的功能,用法有些。

 invoke 主要是处理多线程,在多线程中主要的有线程同步。

参照以下文档:

1.使用IAsyncResult asyncResult属性来判断异步调用是否完成

 

WaitOne的第一个参数表示要等待的毫秒数,在指定时间之内,WaitOne方法将一直等待,直到异步调用完成,并发出通知,WaitOne方法才返回true。当等待指定时间之后,异步调用仍未完成,WaitOne方法返回false,如果指定时间为0,表示不等待,如果为-1,表示永远等待,直到异步调用完成。

 

static void Main(string[] args)
 {

     NewTaskDelegate task = newTask;
    IAsyncResult asyncResult = task.BeginInvoke(2000, null, null);
   while (!asyncRe ==sult.IsCompleted)
     {

          Console.Write("*"); Thread.Sleep(100); } // 由于异步调用已经完成,因此, EndInvoke会立刻返回结果
         int result = task.EndInvoke(asyncResult);
    Console.WriteLine(result);
 }  

 

2.使用WaitOne方法等待异步方法执行完成
static void Main(string[] args)

{

        NewTaskDelegate task = newTask;

        IAsyncResult asyncResult = task.BeginInvoke(2000, null, null);

         while (!asyncResult.AsyncWaitHandle.WaitOne(100, false))

         {

            Console.Write("*");

         }

          int result = task.EndInvoke(asyncResult); Console.WriteLine(result);

 }

 3、使用回调方式返回结果    

 

 上面介绍的几种方法实际上只相当于一种方法。这些方法虽然可以成功返回结果,也可以给用户一些提示,但在这个过程中,整个程序就象死了一样(如果读者在GUI程序中使用这些方法就会非常明显),要想在调用的过程中,程序仍然可以正常做其它的工作,就必须使用异步调用的方式。下面我们使用GUI程序来编写一个例子,代码如下:
private delegate int MyMethod();

private int method()

{

       Thread.Sleep(10000);

        return 100;

}

 private void MethodCompleted(IAsyncResult asyncResult)

 {

     if (asyncResult == null)

          return;

     textBox1.Text = (asyncResult.AsyncState as MyMethod).EndInvoke(asyncResult).ToString();

 }

 private void button1_Click(object sender, EventArgs e)

{  

   MyMethod my = method;

   IAsyncResult asyncResult = my.BeginInvoke(MethodCompleted, my);

 }
    要注意的是,这里使用了BeginInvoke方法的最后两个参数(如果被调用的方法含有参数的话,这些参数将作为BeginInvoke的前面一部分参数,如果没有参数,BeginInvoke就只有两个参数了)。第一个参数是回调方法委托类型,这个委托只有一个参数,就是IAsyncResult,如MethodCompleted方法所示。当method方法执行完后,系统会自动调用MethodCompleted方法。BeginInvoke的第二个参数需要向MethodCompleted方法中传递一些值,一般可以传递被调用方法的委托,如上面代码中的my。这个值可以使用IAsyncResult.AsyncState属性获得。

    由于上面的代码通过异步的方式访问的form上的一个textbox,因此,需要按ctrl+f5运行程序(不能直接按F5运行程序,否则无法在其他线程中访问这个textbox,关于如果在其他线程中访问GUI组件,并在后面的部分详细介绍)。并在form上放一些其他的可视控件,然在点击button1后,其它的控件仍然可以使用,就象什么事都没有发生过一样,在10秒后,在textbox1中将输出100。

  

 

 作者:佚名  http://www.diybl.com/course/4_webprogram/asp.net/netjs/2008714/133128.html

 


   using System;
   using System.Runtime.Remoting.Messaging;
   using System.Threading;
  namespace 等待句柄
  {
  //委托声明(函数签名)
  delegate string MyMethodDelegate();
  class MyClass
  {
   //要调用方法1
   public string Write1()
   {
   for(double i = 0; i < 100000000000;i++)

   Console.WriteLine("执行方法1");
   return "";
   }
   //要调用方法2
   public string Write2()
   {
   Console.WriteLine("执行方法2");
   return "22222222222222";
   }
   //要调用方法3
   public string Write3()
   {
   Console.WriteLine("执行方法3");
   return "33333333333333";
   }
   [STAThread]
   static void Main(string[] args)
   {
   MyClass myClass = new MyClass();
   MyMethodDelegate d1 = new MyMethodDelegate(myClass.Write1);
   MyMethodDelegate d2 = new MyMethodDelegate(myClass.Write2);
   MyMethodDelegate d3 = new MyMethodDelegate(myClass.Write3);
   AsyncResult myResult1,myResult2,myResult3; //此类封闭异步委托异步调用的结果,通过AsyncResult得到结果.
   myResult1 = (AsyncResult)d1.BeginInvoke(null,null); //调用
  
   myResult2 = (AsyncResult)d2.BeginInvoke(null,null);
  
   myResult3 = (AsyncResult)d3.BeginInvoke(null,null);
   //建立WaitHandle数组对象
   WaitHandle[] waitHandle = new WaitHandle[3]{myResult1.AsyncWaitHandle,myResult2.AsyncWaitHandle,myResult3.AsyncWaitHandle};
  /*
   try
   {
   //等待三个异步方法中的至少一个执行完成,才继续执行下面的语句
   WaitHandle.WaitAny(waitHandle);
   }
   catch(Exception ex)
   {
   throw new Exception(ex.Message);
   }
  */
   myResult1.AsyncWaitHandle.WaitOne(); //如果当前异步方法还没有完成,此异步方法执行完毕才往下执行
   myResult2.AsyncWaitHandle.WaitOne();
   myResult3.AsyncWaitHandle.WaitOne();
  /*
   myResult1.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(1),false); //如果当前异步方法还没有完成,则等待一秒的时间执行此方法; 如果一秒后此方法还未完成的话,则不再等待,继续往下执行
   myResult2.AsyncWaitHandle.WaitOne();
   myResult3.AsyncWaitHandle.WaitOne();
  */
  
   Console.WriteLine("测试等待句柄"); //标记语句用.
   Console.Read();
   }
  }
  }
  本示例代码已经测试,能够正常运行!
http://www.wangchao.net.cn/bbsdetail_74766.html

 

原创粉丝点击