C# 多執行緒 用委託實現非同步_呼叫委託的BeginInvoke和EndInvoke方法
阿新 • • 發佈:2019-02-16
1.C#中的每一個委託都內建了BeginInvoke和EndInvoke方法,如果委託的方法列表裡只有一個方法,那麼這個方法就可以非同步執行(不在當前執行緒裡執行,另開闢一個執行緒執行)。委託的BeginInvoke和EndInvoke方法就是為了上述目的而生的。
2.原始執行緒發起了一個非同步執行緒,有如下三種執行方式:
方式一:等待一直到完成,即原始執行緒在發起了非同步執行緒以及做了一些必要處理之後,原始執行緒就中斷並等待非同步執行緒結束再繼續執行。
方式二:輪詢,即原始執行緒定期檢查發起的執行緒是否完成,如果沒有則可以繼續做一些其它事情。
方式三:回撥,即原始執行緒一直執行,無需等待或檢查發起的執行緒是否完成。在發起的執行緒執行結束,發起的執行緒就會呼叫使用者定義好的回撥方法,由這個回撥方法在呼叫EndInvoke之前處理非同步方法執行得到的結果。
3.一個控制檯小程式,使用了上面三種方式,執行結果如下:
4.程式碼:
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Remoting.Messaging; using System.Text; using System.Threading; namespace 用委託實現非同步_呼叫BeginInvoke和EndInvoke方法 { delegate long MyDel(int first,int second); //宣告委託型別 class Program { //宣告委託型別的方法 static long Sum(int x,int y) { Console.WriteLine(" Inside Sum"); Thread.Sleep(200); return x + y; } //定義當非同步執行緒執行結束要執行的回撥函式 static void CallWhenDone(IAsyncResult iar) { Console.WriteLine(" Inside CallWhenDone"); AsyncResult ar = (AsyncResult)iar; MyDel del = (MyDel)ar.AsyncDelegate; long result = del.EndInvoke(iar); Console.WriteLine(" The result is {0}.", result); } //方式一:等待非同步執行緒結束,再繼續執行主執行緒 static void WaitUntilDoneStyle() { MyDel del = new MyDel(Sum); Console.WriteLine("Before BeginInvoke"); IAsyncResult iar = del.BeginInvoke(3, 5, null, null); //開始非同步呼叫 Console.WriteLine("After BeginInvoke"); Console.WriteLine("Doing main stuff before"); long result = del.EndInvoke(iar); //等待非同步執行緒結束並獲取結果 Console.WriteLine("After EndInvoke:{0}", result); Console.WriteLine("Doing main stuff after"); } //方式二:輪詢檢查非同步執行緒是否結束,若沒結束則執行主執行緒 static void LunXunPollingStyle() { MyDel del = new MyDel(Sum); Console.WriteLine("Before BeginInvoke"); IAsyncResult iar = del.BeginInvoke(3, 5, null, null); //開始非同步呼叫 Console.WriteLine("After BeginInvoke"); while (!iar.IsCompleted) { Console.WriteLine("Not Done.Doing main stuff"); //繼續處理主執行緒事情 for (long i = 0; i < 10000000; i++) ; } Console.WriteLine("Done"); long result = del.EndInvoke(iar); //呼叫EndInvoke來獲取結果並進行清理 Console.WriteLine("Result: {0}", result); } //方式三:回撥方式,當非同步執行緒結束,系統呼叫使用者自定義的方法來處理結果(包括呼叫委託的EndInvoke方法) static void CallBackStyle() { MyDel del = new MyDel(Sum); Console.WriteLine("Before BeginInvoke"); IAsyncResult iar = del.BeginInvoke(3, 5, new AsyncCallback(CallWhenDone), null); Console.WriteLine("After BeginInvoke"); Console.WriteLine("Doing more work in main."); Thread.Sleep(500); Console.WriteLine("Done with Main. Exiting."); } static void Main(string[] args) { //方式一:等待非同步執行緒結束,再繼續執行主執行緒 Console.WriteLine(); Console.WriteLine("--------方式一:等待非同步執行緒結束,再繼續執行主執行緒--------"); WaitUntilDoneStyle(); //方式二:輪詢檢查非同步執行緒是否結束,若沒結束則執行主執行緒 Console.WriteLine(); Console.WriteLine("--------方式二:輪詢檢查非同步執行緒是否結束,若沒結束則執行主執行緒--------"); LunXunPollingStyle(); //方式三:回撥方式,當非同步執行緒結束,系統呼叫使用者自定義的方法來處理結果(包括呼叫委託的EndInvoke方法) Console.WriteLine(); Console.WriteLine("--------方式三:回撥方式,當非同步執行緒結束,系統呼叫使用者自定義的方法來處理結果(包括呼叫委託的EndInvoke方法)--------"); CallBackStyle(); } } }