C#異步編程的實現方式(1)——異步委托


異步的實現即多線程,一種簡單的方式就是創建一個委托,然后異步調用它。 .Net Framework已經為我們提供了委托的異步調用方法。下面介紹三種使用委托實現異步的方法。

 

1、投票(IsCompleted屬性)

首先定義一個委托:

   1: public delegate string MyDelegate(int ms);

Delegate類提供了BeginInvoke()方法,這個方法返回一個IAsyncResult接口,這個接口包含了該委托的相關信息,並且可以通過它的IsCompleted屬性來判斷該委托是否執行完成。下面是將要異步調用的方法:

   1: static string DelegateMethod(int ms)
   2: {
   3:     Console.WriteLine("TakesAWhile started");
   4:     Thread.Sleep(ms);
   5:     Console.WriteLine("TakesAWhile completed");
   6:     return "Hello world!";
   7: }

下面是主線程的方法:

   1: static void Imp1()
   2: {
   3:     MyDelegate dl = DelegateMethod;
   4:  
   5:     IAsyncResult ar = dl.BeginInvoke(5000, null, null);
   6:  
   7:     while (!ar.IsCompleted)
   8:     {
   9:         Console.Write(".");
  10:         Thread.Sleep(50);
  11:     }
  12:     string result = dl.EndInvoke(ar);
  13:     Console.WriteLine("result: {0}", result);
  14: }

可以看到,委托線程執行5秒鍾,主線程不停的循環判斷委托線程是否完成(用IsCompleted屬性判斷)。如果沒完成則斷續打點,如果完成則跳出循環。用EndInvoke方法獲取委托的返回值。如果方法未執行完,EndInvoke方法就會一直阻塞,直到被調用的方法執行完畢。

 

2、等待句柄(AsyncWaitHandle屬性)

使用IAsyncResult的AsyncWaitHandle屬性可以訪問等待句柄,這個屬性返回一個WaitHandle對象,這個對象的WaitOne()方法可輸入一個超時時間作為參數,設置等待的最長時間。如果超時,WaitOne()方法返回一個bool值,true為等待成功(即委托完成),異步調用的方法與上面一樣,下面是主線程實現:

   1: static void Imp2()
   2: {
   3:     MyDelegate dl = DelegateMethod;
   4:  
   5:     IAsyncResult ar = dl.BeginInvoke(5000, null, null);
   6:     while (true)
   7:     {
   8:         Console.Write(".");
   9:         if (ar.AsyncWaitHandle.WaitOne(50))
  10:         {
  11:             Console.WriteLine("Can get the result now");
  12:             break;
  13:         }
  14:     }
  15:     string result = dl.EndInvoke(ar);
  16:     Console.WriteLine("result: {0}", result);
  17: }
主線程每等待50秒做一次判斷是否完成。
 
3、異步回調(AsyncCallBack委托)
BeginInvoke方法第二個參數可傳入一個AsnycCallBack委托類型的方法,當異步調用完成時會執行這個方法。我們可以用Lambda表達式來實現:
   1: static void Imp3()
   2: {
   3:     MyDelegate dl = DelegateMethod;
   4:     dl.BeginInvoke(5000, new AsyncCallback(ar =>
   5:     {
   6:         string result = dl.EndInvoke(ar);
   7:         Console.WriteLine("result: {0}", result);
   8:     }), null);
   9:     for (int i = 0; i < 100; i++)
  10:     {
  11:         Console.Write(".");
  12:         Thread.Sleep(50);
  13:     }
  14: }
BeginInvoke方法的最后一個參數可以用IAsyncResult的AsyncState屬性獲取。
 
參考資料:《C#高級編程》
 
本文源代碼:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM