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. }  

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com