Bootstrap

C# 多线程 用委托实现异步_调用委托的BeginInvoke和EndInvoke方法

1.C#中的每一个委托都内置了BeginInvoke和EndInvoke方法,如果委托的方法列表里只有一个方法,那么这个方法就可以异步执行(不在当前线程里执行,另开辟一个线程执行)。委托的BeginInvoke和EndInvoke方法就是为了上述目的而生的。

2.原始线程发起了一个异步线程,有如下三种执行方式:

方式一:等待一直到完成,即原始线程在发起了异步线程以及做了一些必要处理之后,原始线程就中断并等待异步线程结束再继续执行。

方式二:轮询,即原始线程定期检查发起的线程是否完成,如果没有则可以继续做一些其它事情。

方式三:回调,即原始线程一直执行,无需等待或检查发起的线程是否完成。在发起的线程执行结束,发起的线程就会调用用户定义好的回调方法,由这个回调方法在调用EndInvoke之前处理异步方法执行得到的结果。

3.一个控制台小程序,使用了上面三种方式,执行结果如下:


4.代码:

[csharp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Runtime.Remoting.Messaging;  
  5. using System.Text;  
  6. using System.Threading;  
  7.   
  8. namespace 用委托实现异步_调用BeginInvoke和EndInvoke方法  
  9. {  
  10.   
  11.     delegate long MyDel(int first,int second); //声明委托类型  
  12.   
  13.     class Program  
  14.     {  
  15.         //声明委托类型的方法  
  16.         static long Sum(int x,int y)   
  17.         {  
  18.             Console.WriteLine("                    Inside Sum");  
  19.             Thread.Sleep(200);  
  20.             return x + y;  
  21.         }  
  22.   
  23.         //定义当异步线程执行结束要执行的回调函数  
  24.         static void CallWhenDone(IAsyncResult iar)  
  25.         {  
  26.             Console.WriteLine("                    Inside CallWhenDone");  
  27.             AsyncResult ar = (AsyncResult)iar;  
  28.             MyDel del = (MyDel)ar.AsyncDelegate;  
  29.   
  30.             long result = del.EndInvoke(iar);  
  31.             Console.WriteLine("                    The result is {0}.", result);  
  32.         }  
  33.   
  34.         //方式一:等待异步线程结束,再继续执行主线程  
  35.         static void WaitUntilDoneStyle()  
  36.         {  
  37.             MyDel del = new MyDel(Sum);  
  38.             Console.WriteLine("Before BeginInvoke");  
  39.             IAsyncResult iar = del.BeginInvoke(3, 5, nullnull); //开始异步调用  
  40.             Console.WriteLine("After BeginInvoke");  
  41.   
  42.             Console.WriteLine("Doing main stuff before");  
  43.             long result = del.EndInvoke(iar); //等待异步线程结束并获取结果  
  44.             Console.WriteLine("After EndInvoke:{0}", result);  
  45.             Console.WriteLine("Doing main stuff after");  
  46.         }  
  47.   
  48.         //方式二:轮询检查异步线程是否结束,若没结束则执行主线程  
  49.         static void LunXunPollingStyle()  
  50.         {  
  51.             MyDel del = new MyDel(Sum);  
  52.             Console.WriteLine("Before BeginInvoke");  
  53.             IAsyncResult iar = del.BeginInvoke(3, 5, nullnull); //开始异步调用  
  54.             Console.WriteLine("After BeginInvoke");  
  55.   
  56.             while (!iar.IsCompleted)  
  57.             {  
  58.                 Console.WriteLine("Not Done.Doing main stuff");  
  59.                 //继续处理主线程事情  
  60.                 for (long i = 0; i < 10000000; i++)  
  61.                     ;  
  62.             }  
  63.             Console.WriteLine("Done");  
  64.             long result = del.EndInvoke(iar); //调用EndInvoke来获取结果并进行清理  
  65.             Console.WriteLine("Result: {0}", result);  
  66.         }  
  67.   
  68.         //方式三:回调方式,当异步线程结束,系统调用用户自定义的方法来处理结果(包括调用委托的EndInvoke方法)  
  69.         static void CallBackStyle()  
  70.         {  
  71.             MyDel del = new MyDel(Sum);  
  72.             Console.WriteLine("Before BeginInvoke");  
  73.             IAsyncResult iar = del.BeginInvoke(3, 5, new AsyncCallback(CallWhenDone), null);  
  74.             Console.WriteLine("After BeginInvoke");  
  75.             Console.WriteLine("Doing more work in main.");  
  76.             Thread.Sleep(500);  
  77.             Console.WriteLine("Done with Main. Exiting.");  
  78.         }  
  79.   
  80.         static void Main(string[] args)  
  81.         {  
  82.             //方式一:等待异步线程结束,再继续执行主线程  
  83.             Console.WriteLine();  
  84.             Console.WriteLine("--------方式一:等待异步线程结束,再继续执行主线程--------");  
  85.             WaitUntilDoneStyle();  
  86.   
  87.             //方式二:轮询检查异步线程是否结束,若没结束则执行主线程  
  88.             Console.WriteLine();  
  89.             Console.WriteLine("--------方式二:轮询检查异步线程是否结束,若没结束则执行主线程--------");  
  90.             LunXunPollingStyle();  
  91.   
  92.             //方式三:回调方式,当异步线程结束,系统调用用户自定义的方法来处理结果(包括调用委托的EndInvoke方法)  
  93.             Console.WriteLine();  
  94.             Console.WriteLine("--------方式三:回调方式,当异步线程结束,系统调用用户自定义的方法来处理结果(包括调用委托的EndInvoke方法)--------");  
  95.             CallBackStyle();  
  96.         }  
  97.   
  98.          
  99.     }  
  100. }  
;