Async_Await;

async關鍵字只是激活了await關鍵字,在遇到「await」關鍵字方法都是同步運行的。await 表達式表示可等待是一個異步操做點,在該點上,直到等待的異步操做完成方法才能繼續(返回以前的「上下文」中執行),而後從異步方法返回。 在該點同時,將方法掛起,而且返回一個對象到方法的調用方!web

示例:原文(PS 我學習都是照着msdn文檔打一遍的):https://msdn.microsoft.com/zh-cn/library/hh873191(v=vs.120).aspxexpress

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Windows;
 7 using System.Windows.Controls;
 8 using System.Windows.Data;
 9 using System.Windows.Documents;
10 using System.Windows.Input;
11 using System.Windows.Media;
12 using System.Windows.Media.Imaging;
13 using System.Windows.Navigation;
14 using System.Windows.Shapes;
15 
16 // Add a using directive and a reference for System.Net.Http; 
17 using System.Net.Http;
18 
19 namespace AsyncTracer
20 {
21     public partial class MainWindow : Window
22     {
23         public MainWindow()
24         {
25             InitializeComponent();
26         }
27 
28         private async void startButton_Click(object sender, RoutedEventArgs e)
29         {
30             // The display lines in the example lead you through the control shifts.
31             resultsTextBox.Text += "ONE:   Entering startButton_Click.\r\n" +
32                 "           Calling AccessTheWebAsync.\r\n";
33 
34             Task<int> getLengthTask = AccessTheWebAsync();
35 
36             resultsTextBox.Text += "\r\nFOUR:  Back in startButton_Click.\r\n" +
37                 "           Task getLengthTask is started.\r\n" +
38                 "           About to await getLengthTask -- no caller to return to.\r\n";
39 
40             int contentLength = await getLengthTask;
41 
42             resultsTextBox.Text += "\r\nSIX:   Back in startButton_Click.\r\n" +
43                 "           Task getLengthTask is finished.\r\n" +
44                 "           Result from AccessTheWebAsync is stored in contentLength.\r\n" +
45                 "           About to display contentLength and exit.\r\n";
46 
47             resultsTextBox.Text +=
48                 String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
49         }
50 
51 
52         async Task<int> AccessTheWebAsync()
53         {
54             resultsTextBox.Text += "\r\nTWO:   Entering AccessTheWebAsync.";
55 
56             // Declare an HttpClient object.
57             HttpClient client = new HttpClient();
58 
59             resultsTextBox.Text += "\r\n           Calling HttpClient.GetStringAsync.\r\n";
60 
61             // GetStringAsync returns a Task<string>. 
62             Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
63             //若是不須要顯示這些文字,上面就能夠直接await;await會阻塞本方法;
64             resultsTextBox.Text += "\r\nTHREE: Back in AccessTheWebAsync.\r\n" +
65                 "           Task getStringTask is started.";
66 
67             // AccessTheWebAsync can continue to work until getStringTask is awaited.No await No asynchronous;
68            
69             resultsTextBox.Text +=
70                 "\r\n           About to await getStringTask and return a Task<int> to startButton_Click.\r\n";
71 
72             // Retrieve the website contents when task is complete. 
73             string urlContents = await getStringTask;
74 
75             resultsTextBox.Text += "\r\nFIVE:  Back in AccessTheWebAsync." +
76                 "\r\n           Task getStringTask is complete." +
77                 "\r\n           Processing the return statement." +
78                 "\r\n           Exiting from AccessTheWebAsync.\r\n";
79 
80             return urlContents.Length;
81         }
82     }
83 }

執行結果:promise

ONE:   Entering startButton_Click.
           Calling AccessTheWebAsync.

TWO:   Entering AccessTheWebAsync.
           Calling HttpClient.GetStringAsync.

THREE: Back in AccessTheWebAsync.
           Task getStringTask is started.
           About to await getStringTask & return a Task<int> to startButton_Click.

FOUR:  Back in startButton_Click.
           Task getLengthTask is started.
           About to await getLengthTask -- no caller to return to.

FIVE:  Back in AccessTheWebAsync.
           Task getStringTask is complete.
           Processing the return statement.
           Exiting from AccessTheWebAsync.

SIX:   Back in startButton_Click.
           Task getLengthTask is finished.
           Result from AccessTheWebAsync is stored in contentLength.
           About to display contentLength and exit.

Length of the downloaded string: 33946.

跟蹤程序:異步

步驟一和二
  當 startButton_Click 調用 AccessTheWebAsync,且 AccessTheWebAsync 調用異步 HttpClient 方法 GetStringAsync(String) 時,前兩個顯示行跟蹤該路徑。 下圖概述了從方法到方法的調用。

AccessTheWebAsync 和 client.GetStringAsync 的返回類型是 Task 對於 AccessTheWebAsync,TResult 是整數。 對於GetStringAsync,TResult 是字符串。因此說await異步等待的方法跟此方法返回的類型能夠不一樣; 當控件轉換回調用方時,任務返回的異步方法返回任務實例。 當調用方法中出現 Await 或 await 運算符,或當調用方法結束時,控件從異步方法返回其調用方。 async

步驟三:學習

在 AccessTheWebAsync 中,調用異步方法 GetStringAsync(String) 可下載目標網頁的內容。 控件從 client.GetStringAsync 返回到AccessTheWebAsync,當 client.GetStringAsync 返回。ui

client.GetStringAsync 方法返回分配給 AccessTheWebAsync 中 getStringTask 變量的字符串的任務。url

Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");  

您能夠將任務視爲 client.GetStringAsync 作出的承諾,以便最終生成一個實際字符串。 同時,若是 AccessTheWebAsync 要執行不依賴client.GetStringAsync 承諾的字符串的工做(也是下面的代碼若是跟client.GetStringAsync返回的結果無關,沒必要await等待,執行完再await),則該工做在 client.GetStringAsync 等待時繼續。 在示例中,如下輸出行(標記爲「THREE」)表示能夠單獨操做。spa

THREE: Back in AccessTheWebAsync.
           Task getStringTask is started.
           About to await getStringTask & return a Task<int> to startButton_Click.

  當等待 getStringTask 時,下面的語句會掛起 AccessTheWebAsync 中的進程。調用方繼續執行,直至遇到await;.net

string urlContents = await getStringTask;

下圖顯示了從 client.GetStringAsync 到 getStringTask 的分配和從 getStringTask 的建立到等待運算符的應用程序的控制流。

 

重點:等待表達式掛起 AccessTheWebAsync 直到 client.GetStringAsync 返回。 同時,控件返回至 AccessTheWebAsync、startButton_Click 的調用方。

步驟四:

AccessTheWebAsync 的聲明的返回類型是Task<int>。 所以,當 AccessTheWebAsync 掛起時,它向 startButton_Click 返回整數任務。 你應瞭解返回的任務並非 getStringTask。 返回的任務是表示掛起的方法中仍要執行的整數的新任務 AccessTheWebAsync。 當任務完成時,任務是 AccessTheWebAsync 中的一個承諾以生成整數。
主調用方的下面的語句將此任務分配給 getLengthTask 變量。
Task<int> getLengthTask = AccessTheWebAsync();

  正如在 AccessTheWebAsync 中,startButton_Click 可繼續那些不依賴於異步任務結果的工做 (getLengthTask) 直到任務處於等待狀態。 下面的輸出行表示該工做。

FOUR:  Back in startButton_Click.
           Task getLengthTask is started.
           About to await getLengthTask -- no caller to return to.
當 getLengthTask 等待時,startButton_Click 中的進程將被掛起。 下面的賦值語句會掛起 startButton_Click 直到 AccessTheWebAsync 完成。
int contentLength = await getLengthTask;

在下圖中,箭頭顯示從 AccessTheWebAsync 中的 await 表達式到賦值給 getLengthTask 的控制流,接着是在 startButton_Click 中進行通常處理,直到等待 getLengthTask。

步驟五:

若是 client.GetStringAsync 發出了已完成信號,AccessTheWebAsync 中的處理過程就能夠從掛起中釋放並繼續到 await 語句後。 輸出的如下行表示處理的恢復。

FIVE:  Back in AccessTheWebAsync.
           Task getStringTask is complete.
           Processing the return statement.
           Exiting from AccessTheWebAsync.

返回語句 urlContents.Length 的操做存儲在 AccessTheWebAsync 返回的任務中。 等待表達式從 startButton_Click 中的 getLengthTask 檢索該值。

下圖顯示 client.GetStringAsync(和 getStringTask)完成後的控件傳輸。

若是 AccessTheWebAsync 發出了已完成信號,處理過程就能夠繼續到 startButton_Async中的 await 語句後。 實際上,程序沒有其餘要執行的操做。

輸出的如下行表示 startButton_Async 中處理的恢復:

SIX:   Back in startButton_Click.
           Task getLengthTask is finished.
           Result from AccessTheWebAsync is stored in contentLength.
           About to display contentLength and exit.

等待表達式是從做爲 AccessTheWebAsync 中返回語句的操做數的 getLengthTask 整數值中檢索的。 下面的語句將該值分配給 contentLength變量。

int contentLength = await getLengthTask;

下圖顯示了從 AccessTheWebAsync 到 startButton_Click 的控制返回。

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息