C# 多线程 用委托实现异步_调用委托的BeginInvoke和EndInvoke方法
1.C#中的每一个委托都内置了BeginInvoke和EndInvoke方法,如果委托的方法列表里只有一个方法,那么这个方法就可以异步执行(不在当前线程里执行,另开辟一个线程执行)。委托的BeginInvoke和EndInvoke方法就是为了上述目的而生的。
2.原始线程发起了一个异步线程,有如下三种执行方式:
方式一:等待一直到完成,即原始线程在发起了异步线程以及做了一些必要处理之后,原始线程就中断并等待异步线程结束再继续执行。
方式二:轮询,即原始线程定期检查发起的线程是否完成,如果没有则可以继续做一些其它事情。
方式三:回调,即原始线程一直执行,无需等待或检查发起的线程是否完成。在发起的线程执行结束,发起的线程就会调用用户定义好的回调方法,由这个回调方法在调用EndInvoke之前处理异步方法执行得到的结果。
3.一个控制台小程序,使用了上面三种方式,执行结果如下:
4.代码:
1 [csharp] view plain copy 2 3 using System; 4 using System.Collections.Generic; 5 using System.Linq; 6 using System.Runtime.Remoting.Messaging; 7 using System.Text; 8 using System.Threading; 9 10 namespace 用委托实现异步_调用BeginInvoke和EndInvoke方法 11 { 12 13 delegate long MyDel(int first,int second); //声明委托类型 14 15 class Program 16 { 17 //声明委托类型的方法 18 static long Sum(int x,int y) 19 { 20 Console.WriteLine(" Inside Sum"); 21 Thread.Sleep(200); 22 return x + y; 23 } 24 25 //定义当异步线程执行结束要执行的回调函数 26 static void CallWhenDone(IAsyncResult iar) 27 { 28 Console.WriteLine(" Inside CallWhenDone"); 29 AsyncResult ar = (AsyncResult)iar; 30 MyDel del = (MyDel)ar.AsyncDelegate; 31 32 long result = del.EndInvoke(iar); 33 Console.WriteLine(" The result is {0}.", result); 34 } 35 36 //方式一:等待异步线程结束,再继续执行主线程 37 static void WaitUntilDoneStyle() 38 { 39 MyDel del = new MyDel(Sum); 40 Console.WriteLine("Before BeginInvoke"); 41 IAsyncResult iar = del.BeginInvoke(3, 5, null, null); //开始异步调用 42 Console.WriteLine("After BeginInvoke"); 43 44 Console.WriteLine("Doing main stuff before"); 45 long result = del.EndInvoke(iar); //等待异步线程结束并获取结果 46 Console.WriteLine("After EndInvoke:{0}", result); 47 Console.WriteLine("Doing main stuff after"); 48 } 49 50 //方式二:轮询检查异步线程是否结束,若没结束则执行主线程 51 static void LunXunPollingStyle() 52 { 53 MyDel del = new MyDel(Sum); 54 Console.WriteLine("Before BeginInvoke"); 55 IAsyncResult iar = del.BeginInvoke(3, 5, null, null); //开始异步调用 56 Console.WriteLine("After BeginInvoke"); 57 58 while (!iar.IsCompleted) 59 { 60 Console.WriteLine("Not Done.Doing main stuff"); 61 //继续处理主线程事情 62 for (long i = 0; i < 10000000; i++) 63 ; 64 } 65 Console.WriteLine("Done"); 66 long result = del.EndInvoke(iar); //调用EndInvoke来获取结果并进行清理 67 Console.WriteLine("Result: {0}", result); 68 } 69 70 //方式三:回调方式,当异步线程结束,系统调用用户自定义的方法来处理结果(包括调用委托的EndInvoke方法) 71 static void CallBackStyle() 72 { 73 MyDel del = new MyDel(Sum); 74 Console.WriteLine("Before BeginInvoke"); 75 IAsyncResult iar = del.BeginInvoke(3, 5, new AsyncCallback(CallWhenDone), null); 76 Console.WriteLine("After BeginInvoke"); 77 Console.WriteLine("Doing more work in main."); 78 Thread.Sleep(500); 79 Console.WriteLine("Done with Main. Exiting."); 80 } 81 82 static void Main(string[] args) 83 { 84 //方式一:等待异步线程结束,再继续执行主线程 85 Console.WriteLine(); 86 Console.WriteLine("--------方式一:等待异步线程结束,再继续执行主线程--------"); 87 WaitUntilDoneStyle(); 88 89 //方式二:轮询检查异步线程是否结束,若没结束则执行主线程 90 Console.WriteLine(); 91 Console.WriteLine("--------方式二:轮询检查异步线程是否结束,若没结束则执行主线程--------"); 92 LunXunPollingStyle(); 93 94 //方式三:回调方式,当异步线程结束,系统调用用户自定义的方法来处理结果(包括调用委托的EndInvoke方法) 95 Console.WriteLine(); 96 Console.WriteLine("--------方式三:回调方式,当异步线程结束,系统调用用户自定义的方法来处理结果(包括调用委托的EndInvoke方法)--------"); 97 CallBackStyle(); 98 } 99 100 101 } 102 }