異步編程,await async入門

網上不少異步編程的文章,提供一篇入門:算法

異步編程模型編程

.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

相關文章
相關標籤/搜索