網上不少異步編程的文章,提供一篇入門:算法
異步編程模型編程
.net支持3種異步編程模式:設計模式
msdn:https://docs.microsoft.com/zh-cn/dotnet/standard/asynchronous-programming-patterns/異步
推薦你們先看我寫的,再針對各個部分查看msdn的詳細內容async
一、 異步編程模型 (APM:Asynchronous Programming Model)ide
使用 IAsyncResult 設計模式的異步操做是經過名爲 BeginOperationName 和 EndOperationName 的兩個方法來實現的,這兩個方法分別開始和結束異步操做 OperationName異步編程
開始異步操做單元測試
BeginOperationName 方法開始異步操做 OperationName,並返回實現 IAsyncResult 接口的對象。 IAsyncResult 對象存儲有關異步操做的信息。測試
結束異步操做ui
EndOperationName 方法用於結束異步操做 OperationName。 EndOperationName 方法的返回值與其同步對應方法的返回值類型相同,而且是特定於異步操做的。
在msdn上是以文件讀取做爲例子。這裏以更簡單的例子進行演示。若是能夠進行單元測試的,可直接在單元測試中進行,沒有的則可使用控制檯應用程序進行。
委託對象有以BeginInvoke和EndInvoke,因此使用委託進行演示:
1.1要被調用的方法:這是一個帶有參數且有字符串返回值的方法
1 static string ShowInfo(string info) 2 3 { 4 5 Console.WriteLine("方法調用"+info); 6 7 int result = 0; 8 9 for (int i = 1; i < 100; i++) 10 11 { 12 13 result += i; 14 15 System.Threading.Thread.Sleep(10); 16 17 } 18 19 return result.ToString(); 20 21 }
|
以上方法,一個輸入,一個輸出,都是字串,方法體中會打印方法調用字樣,並打印輸入字串。而後計算1到99的數字的和值,其中每次數字輸出會休眠10毫秒。最後返回和值。
以上僅爲演示和模擬算法效果。
1.2
1 //委託對象 2 3 static SayHi xx = new SayHi(ShowInfo); 4 5 static void Main(string[] args) 6 7 { 8 9 //回調委託對象 10 11 AsyncCallback callback = new AsyncCallback(show); 12 13 //異步開始 14 15 var ret=xx.BeginInvoke("", null, null); 16 17 string result = xx.EndInvoke(ret); 18 19 Console.WriteLine(result); 20 21 Console.Read(); 22 23 }
|
以上方法,先定義了一個與1.1中方法ShowInfo方法匹配的委託:即此委託對象能夠apm異步調用,即異步調用 ShowInfo方法。
在BeginInvoke時,第二個參數,即回調方法設置爲null,即不使用回調方法。
BeginInvoke方法以下:
public IAsyncResult BeginInvoke (
InvokeArgs invokeArgs,
AsyncCallback callback,
Object userState
)
第一個參數是委託方法的參數:ShowInfo方法的輸入參數
第二個參數是回調方法:完成調用ShowInfo方法後要執行的動做,這裏是個(回調)方法
第三個參數是操做關聯的可選狀態
EndInvoke方法以下:
public InvokeCompletedResult EndInvoke (
IAsyncResult asyncResult
)
參數是 BeginInvoke方法的返回值。而返回值是InvokeCompletedResult類型,委託對象的返回值,即方法ShowInfo的返回值。
BeginInvoke方法的返回值爲IAsyncResult類型。第二個參數爲AsyncCallback類型。
AsyncCallback是一個委託類型,查看它的定義是這樣的:
public delegate void AsyncCallback(IAsyncResult ar);
它是一個無返回值參數是IAsyncResult類型的委託。因此回調方法簽名與與這相符,定義回調方法以下:
//回調方法 static void show(IAsyncResult asr) { string result = xx.EndInvoke(asr); Console.WriteLine(result); Console.WriteLine("結束"); }
二、 基於事件的異步模式 (EAP)
未完待
三、 基於任務的異步模式 (TAP)
與之離不開的是Task類。它的構造方法以下:
即,接收action委託。
最簡單的調用以下:
1 static void Main(string[] args) 2 3 { 4 5 Action act=delegate() 6 7 { 8 9 Console.WriteLine("方法打印信息"); 10 11 }; 12 13 Task t = new Task(act); 14 15 t.Start(); 16 17 Console.Read(); 18 19 }
|
經過匿名方法,lambda能夠省略爲:
1 static void Main(string[] args) 2 3 { 4 5 //Action act=delegate() 6 7 //{ 8 9 // Console.WriteLine("方法打印信息"); 10 11 //}; 12 13 Task t = new Task(()=>{ 14 15 Console.WriteLine("方法打印信息"); 16 17 }); 18 19 t.Start(); 20 21 Console.Read(); 22 23 }
|
此外,能夠經過Task的靜態工廠建立任務,以下:
1 Task t = Task.Factory.StartNew( 2 3 () => { 4 5 Console.WriteLine("方法打印信息"); 6 7 } 8 9 ); 10 11 t.Start(); 12 13 Console.Read();
|
總之,效果是同樣的。
如下代碼用於演示同步:
1 static void Main(string[] args) 2 3 { 4 5 Console.WriteLine(1); 6 7 Console.WriteLine(2); 8 9 Task taskA = Task.Run(() => { Thread.Sleep(2000); Console.WriteLine(3); }); 10 11 try 12 13 { 14 15 taskA.Wait(); 16 17 Console.WriteLine(4); 18 19 } 20 21 catch (AggregateException) 22 23 { 24 25 Console.WriteLine("Exception in taskA."); 26 27 } 28 29 Console.WriteLine(5); 30 31 Console.Read(); 32 33 }
|
首先main輸出 1和2,而後此時插入任務taskA。它在休眠2秒後,輸出3,而後任務結束後輸出4,最後main中輸出5。
任務taskA執行完畢後大概須要2秒鐘的時間,這樣,若是不等待taskA,即taskA啓動執行後,不等待執行完畢,則會執行輸出 4和5。
最終打印結果是:1,2,4,5,3(順序是這樣的,但格式是帶回車的)
若是進行等待,Wait() 不帶參數,表示一直等待到任務執行完畢。
這樣,就能夠按順序輸出了,最終結果是:1,2,3,4,5
一樣的Task類有對應的泛型類型,這裏不演示了。
await
msdn: https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/await
await運算符用於異步方法中的任務,在方法的執行中插入掛起點,直到所等待的任務完成。僅可用於由async關鍵字修改的異步方法中。
應用await運算符的任務一般由實現基於任務的異步模式的方法調用返回。包括:Task,Task<TResult>,ValueTask 和ValueTask<TResult> 對象的方法。
async
msdn: https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/async
async修飾符可將方法、lambda表達式,匿名方法指定爲異步,帶此修飾符的方法或表達式稱爲異步方法。
Msdn上一個很是好的例子:它是有順序的執行任務,這樣經過await達到同步的結果,
https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/async/index