自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C#異步方法和同步方法的差異淺談

開發(fā) 后端
C#異步方法和同步方法的差異是什么呢?C#異步方法在使用上和意義上與C#同步方法有何不同?那么本文就向你介紹這方面的內(nèi)容。

C#異步方法和同步方法的差異是什么呢?

C#同步方法調(diào)用在程序繼續(xù)執(zhí)行之前需要等待同步方法執(zhí)行完畢返回結果

C#異步方法則在被調(diào)用之后立即返回以便程序在被調(diào)用方法完成其任務的同時執(zhí)行其它操作

異步編程概覽

.NET Framework 允許您異步調(diào)用任何方法。定義與您需要調(diào)用的方法具有相同簽名的委托;公共語言運行庫將自動為該委托定義具有適當簽名

的 BeginInvoke 和 EndInvoke 方法。

BeginInvoke 方法用于啟動異步調(diào)用。它與您需要異步執(zhí)行的方法具有相同的參數(shù),只不過還有兩個額外的參數(shù)(將在稍后描述)。

BeginInvoke 立即返回,不等待異步調(diào)用完成。

BeginInvoke 返回 IasyncResult,可用于監(jiān)視調(diào)用進度。

EndInvoke 方法用于檢索異步調(diào)用結果。調(diào)用BeginInvoke后可隨時調(diào)用EndInvoke方法;如果異步調(diào)用未完成,EndInvoke 將一直阻塞到

異步調(diào)用完成。EndInvoke的參數(shù)包括您需要異步執(zhí)行的方法的out和ref參數(shù)(在 Visual Basic 中為 <Out> ByRef 和 ByRef)以及由BeginInvoke 返回的IAsyncResult。

四種C#異步方法使用 BeginInvoke 和 EndInvoke 進行異步調(diào)用。調(diào)用了BeginInvoke后,可以:

1.進行某些操作,然后調(diào)用 EndInvoke 一直阻塞到調(diào)用完成。

2.使用 IAsyncResult.AsyncWaitHandle 獲取 WaitHandle,使用它的 WaitOne 方法將執(zhí)行一直阻塞到發(fā)出 WaitHandle 信號,然后調(diào)用EndInvoke。這里主要是主程序等待異步方法,等待異步方法的結果。

3.輪詢由 BeginInvoke 返回的 IAsyncResult,IAsyncResult.IsCompeted確定異步調(diào)用何時完成,然后調(diào)用 EndInvoke。此處理個人認為與相同。

4.將用于回調(diào)方法的委托傳遞給 BeginInvoke。該方法在異步調(diào)用完成后在 ThreadPool 線程上執(zhí)行,它可以調(diào)用 EndInvoke。這是在強制裝換回調(diào)函數(shù)里面IAsyncResult.AsyncState(BeginInvoke方法的最后一個參數(shù))成委托,然后用委托執(zhí)行EndInvoke。

警告   始終在異步調(diào)用完成后調(diào)用 EndInvoke。

以上有不理解的稍后可以再理解。

C#異步方法例子

1)先來個簡單的沒有回調(diào)函數(shù)的異步方法例子

請再運行程序的時候,仔細看注釋,對理解很有幫助。還有,若將注釋的中的兩個方法都同步,你會發(fā)現(xiàn)異步運行的速度優(yōu)越性。

  1. using System;  
  2.  namespace ConsoleApplication1  
  3.  {  
  4.  class Class1  
  5.  {  
  6.  //聲明委托  
  7.  public delegate void AsyncEventHandler();  
  8.    
  9.  //C#異步方法  
  10.  void Event1()  
  11. {  
  12. Console.WriteLine("Event1 Start");  
  13. System.Threading.Thread.Sleep(4000);  
  14. Console.WriteLine("Event1 End");  
  15. }  
  16. // C#同步方法  
  17. void Event2()  
  18. {  
  19. Console.WriteLine("Event2 Start");  
  20. int i=1;  
  21. while(i<1000)  
  22. {  
  23. i=i+1;  
  24. Console.WriteLine("Event2 "+i.ToString());  
  25. }  
  26. Console.WriteLine("Event2 End");  
  27. }  
  28. [STAThread]  
  29. static void Main(string[] args)  
  30. {  
  31. long start=0;  
  32. long end=0;  
  33. Class1 c = new Class1();  
  34. Console.WriteLine("ready");  
  35. start=DateTime.Now.Ticks;  
  36.  
  37. //實例委托  
  38. AsyncEventHandler asy = new AsyncEventHandler(c.Event1);  
  39. //C#異步方法:異步調(diào)用開始,沒有回調(diào)函數(shù)和AsyncState,都為null  
  40. IAsyncResult ia = asy.BeginInvoke(nullnull);  
  41. //C#同步方法:同步開始,  
  42. c.Event2();  
  43. //異步結束,若沒有結束,一直阻塞到調(diào)用完成,在此返回該函數(shù)的return,若有返回值。   
  44. asy.EndInvoke(ia);  
  45.  
  46. //都同步的情況。  
  47. //c.Event1();  
  48. //c.Event2();  
  49.      
  50. end =DateTime.Now.Ticks;  
  51. Console.WriteLine("時間刻度差="+ Convert.ToString(end-start) );  
  52. Console.ReadLine();  
  53. }  
  54. }  

2)下面看有回調(diào)函數(shù)的WebRequest和WebResponse的異步操作。

  1. using System;  
  2. using System.Net;  
  3. using System.Threading;  
  4. using System.Text;  
  5. using System.IO;  
  6. // RequestState 類用于通過  
  7. // 異步調(diào)用傳遞數(shù)據(jù)  
  8. public class RequestState  
  9. {  
  10. const int BUFFER_SIZE = 1024;  
  11. public StringBuilder RequestData;  
  12. public byte[] BufferRead;  
  13. public HttpWebRequest Request;  
  14. public Stream ResponseStream;  
  15. // 創(chuàng)建適當編碼類型的解碼器  
  16. public Decoder StreamDecode = Encoding.UTF8.GetDecoder();  
  17.  
  18. public RequestState()  
  19. {  
  20. BufferRead = new byte[BUFFER_SIZE];  
  21. RequestData = new StringBuilder("");  
  22. Request = null;  
  23. ResponseStream = null;  
  24. }  
  25. }  
  26. // ClientGetAsync 發(fā)出異步請求  
  27. class ClientGetAsync  
  28. {  
  29. public static ManualResetEvent allDone =   
  30. new ManualResetEvent(false);  
  31. const int BUFFER_SIZE = 1024;  
  32.  
  33. public static void Main(string[] args)  
  34. {  
  35. if (args.Length < 1)  
  36. {  
  37. showusage();  
  38. return;  
  39. }  
  40. // 從命令行獲取 URI  
  41. Uri HttpSite = new Uri(args[0]);  
  42.  
  43. // 創(chuàng)建請求對象  
  44. HttpWebRequest wreq = (HttpWebRequest)WebRequest.Create(HttpSite);  
  45.  
  46. // 創(chuàng)建狀態(tài)對象  
  47. RequestState rs = new RequestState();  
  48.  
  49. // 將請求添加到狀態(tài),以便它可以被來回傳遞  
  50. rs.Request = wreq;  
  51.  
  52. // 發(fā)出異步請求  
  53. IAsyncResult r = (IAsyncResult)wreq.BeginGetResponse(  
  54. new AsyncCallback(RespCallback), rs);  
  55.  
  56. // 將 ManualResetEvent 設置為 Wait,  
  57. // 以便在調(diào)用回調(diào)前,應用程序不退出  
  58. allDone.WaitOne();  
  59. }  
  60. public static void showusage()  
  61. {  
  62. Console.WriteLine("嘗試獲取 (GET) 一個 URL");  
  63. Console.WriteLine("\r\n用法::");  
  64. Console.WriteLine("ClientGetAsync URL");  
  65. Console.WriteLine("示例::");  
  66. Console.WriteLine("ClientGetAsync http://www.microsoft.com/net/");  
  67. }  
  68.  
  69. private static void RespCallback(IAsyncResult ar)  
  70. {  
  71. // 從異步結果獲取 RequestState 對象  
  72. RequestState rs = (RequestState)ar.AsyncState;  
  73.  
  74. // 從 RequestState 獲取 HttpWebRequest  
  75. HttpWebRequest req = rs.Request;  
  76.  
  77. // 調(diào)用 EndGetResponse 生成 HttpWebResponse 對象  
  78. // 該對象來自上面發(fā)出的請求  
  79. HttpWebResponse resp = (HttpWebResponse)req.EndGetResponse(ar);  
  80.  
  81. // 既然我們擁有了響應,就該從  
  82. // 響應流開始讀取數(shù)據(jù)了  
  83. Stream ResponseStream = resp.GetResponseStream();  
  84.  
  85. // 該讀取操作也使用異步完成,所以我們  
  86. // 將要以 RequestState 存儲流  
  87. rs.ResponseStream = ResponseStream;  
  88.  
  89. // 請注意,rs.BufferRead 被傳入到 BeginRead。  
  90. // 這是數(shù)據(jù)將被讀入的位置。  
  91. IAsyncResult iarRead = ResponseStream.BeginRead(  
  92. rs.BufferRead, 0, BUFFER_SIZE,   
  93. new AsyncCallback(ReadCallBack), rs);  
  94. }  
  95. private static void ReadCallBack(IAsyncResult asyncResult)  
  96. {  
  97. // 從 asyncresult 獲取 RequestState 對象  
  98. RequestState rs = (RequestState)asyncResult.AsyncState;  
  99.  
  100. // 取出在 RespCallback 中設置的 ResponseStream  
  101. Stream responseStream = rs.ResponseStream;  
  102.  
  103. // 此時 rs.BufferRead 中應該有一些數(shù)據(jù)。  
  104. // 讀取操作將告訴我們那里是否有數(shù)據(jù)  
  105. int read = responseStream.EndRead(asyncResult);  
  106.  
  107. if (read > 0)  
  108. {  
  109. // 準備 Char 數(shù)組緩沖區(qū),用于向 Unicode 轉換  
  110. Char[] charBuffer = new Char[BUFFER_SIZE];  
  111.  
  112. // 將字節(jié)流轉換為 Char 數(shù)組,然后轉換為字符串  
  113. // len 顯示多少字符被轉換為 Unicode  
  114. int len = rs.StreamDecode.GetChars(  
  115. rs.BufferRead, 0, read, charBuffer, 0);  
  116. String str = new String(charBuffer, 0, len);  
  117.  
  118. // 將最近讀取的數(shù)據(jù)追加到 RequestData stringbuilder 對象中,  
  119. // 該對象包含在 RequestState 中  
  120. rs.RequestData.Append(str);  
  121.  
  122.  
  123. // 現(xiàn)在發(fā)出另一個異步調(diào)用,讀取更多的數(shù)據(jù)  
  124. // 請注意,將不斷調(diào)用此過程,直到  
  125. // responseStream.EndRead 返回 -1  
  126. IAsyncResult ar = responseStream.BeginRead(  
  127. rs.BufferRead, 0, BUFFER_SIZE,   
  128. new AsyncCallback(ReadCallBack), rs);  
  129. }  
  130. else 
  131. {  
  132. if (rs.RequestData.Length > 1)  
  133. {  
  134. // 所有數(shù)據(jù)都已被讀取,因此將其顯示到控制臺  
  135. string strContent;  
  136. strContent = rs.RequestData.ToString();  
  137. Console.WriteLine(strContent);  
  138. }  
  139.  
  140. // 關閉響應流  
  141. responseStream.Close();  
  142.  
  143. // 設置 ManualResetEvent,以便主線程可以退出  
  144. allDone.Set();  
  145. }  
  146. return;  
  147. }  

在這里有回調(diào)函數(shù),且異步回調(diào)中又有異步操作。

首先是異步獲得ResponseStream,然后異步讀取數(shù)據(jù)。

這個程序非常經(jīng)典。從中可以學到很多東西的。我們來共同探討。

C#異步方法和同步方法的差異總結

上面說過,.net framework 可以異步調(diào)用任何方法。所以異步用處廣泛。

在.net framework 類庫中也有很多異步調(diào)用的方法。一般都是已Begin開頭End結尾構成一對,異步委托方法,外加兩個回調(diào)函數(shù)和AsyncState參數(shù),組成異步操作的宏觀體現(xiàn)。所以要做異步編程,不要忘了委托delegate、Begin,End,AsyncCallBack委托,AsyncState實例(在回調(diào)函數(shù)中通過IAsyncResult.AsyncState來強制轉換),IAsycResult(監(jiān)控異步),就足以理解異步真諦了。

C#異步方法和同步方法的差異的基本內(nèi)容就向你介紹到這里,希望對你了解和學習C#異步方法和同步方法的差異有所幫助。

【編輯推薦】

  1. C#異步通信概念及應用淺析
  2. C#異步調(diào)用概念及理解淺談
  3. C#異步套接字實現(xiàn)淺析
  4. C#異步初步實例實現(xiàn)詳解
  5. C#異步網(wǎng)絡編程兩大方法淺析
責任編輯:仲衡 來源: 博客園
相關推薦

2009-08-25 16:16:43

C# oledbcon

2009-08-14 17:58:05

C#接口方法

2009-08-28 12:25:58

C#靜態(tài)方法

2011-04-08 09:52:44

C++C#DLL

2009-09-07 03:23:40

C# Main方法

2009-10-20 16:48:30

C#委托

2011-03-25 10:25:30

同步方法同步代碼塊

2009-08-21 11:02:55

C#異步調(diào)用

2010-08-13 09:35:08

C#靜態(tài)

2010-12-21 14:21:36

線程C#

2009-08-19 15:08:30

C#泛型

2012-07-27 10:02:39

C#

2009-08-21 10:17:14

C#異步網(wǎng)絡編程

2009-08-20 19:08:30

C#異步調(diào)用

2009-08-04 16:58:21

C#線程BeginInvokeEndInvoke

2009-08-17 17:40:53

C# GetAllCu

2009-08-26 09:50:08

C# GreetPeo

2009-08-26 17:16:22

C# CheckSta

2024-10-11 11:54:14

C#編寫異步

2009-08-11 13:13:09

C#和Java比較
點贊
收藏

51CTO技術棧公眾號