await太不容易理解了,本身經常迷惑,不知道該怎麼用。html
文章:探索c#之Async、Await剖析編程
這篇文章,有一個很清晰的描述:c#
使用Async標記方法Async1爲異步方法,用Await標記GetRequestStreamAsync表示方法內須要耗時的操做。主線程碰到await時會當即返回,繼續以非阻塞形式執行主線程下面的邏輯。當await耗時操做完成時,繼續執行Async1下面的邏輯。網絡
static async void Async1() { HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("http://cnblogs.com/"); await myReq.GetRequestStreamAsync(); //to do 當上面await耗時任務完成後,程序會回到await標記的地方繼續往下執行
Console.WriteLine("請求結束了");//網絡請求結束,會執行該輸出
DoSomeThing();
DoSomeThing2();
DoSomeThing3();
//方法結束 }
以上文章能夠詳細閱讀,在看本文。異步
能夠反覆閱讀微軟的介紹文章,文章標題:使用 Async 和 Await 的異步編程 (C#)async
地址:https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/async/indexide
使用「async」
關鍵字定義的異步方法簡稱爲「異步方法」。異步編程
下面是微軟的官方示例異步方法代碼:post
// Three things to note in the signature: // - The method has an async modifier. // - The return type is Task or Task<T>. (See "Return Types" section.) // Here, it is Task<int> because the return statement returns an integer. // - The method name ends in "Async." async Task<int> AccessTheWebAsync() { // You need to add a reference to System.Net.Http to declare client. HttpClient client = new HttpClient(); // GetStringAsync returns a Task<string>. That means that when you await the // task you'll get a string (urlContents). Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com"); // You can do work here that doesn't rely on the string from GetStringAsync. DoIndependentWork(); // The await operator suspends AccessTheWebAsync. // - AccessTheWebAsync can't continue until getStringTask is complete. // - Meanwhile, control returns to the caller of AccessTheWebAsync. // - Control resumes here when getStringTask is complete. // - The await operator then retrieves the string result from getStringTask. string urlContents = await getStringTask; // The return statement specifies an integer result. // Any methods that are awaiting AccessTheWebAsync retrieve the length value. return urlContents.Length; }
這個方法須要注意四個地方:ui
1,方法返回類型前的關鍵字「async」;
2,異步方法名稱以Async結尾,表示方法是異步方法(這是一種慣例,或者說約定……);
3, 方法內部有一段很差理解:
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com"); // You can do work here that doesn't rely on the string from GetStringAsync. DoIndependentWork();
client的靜態方法GetStringAsync也是個異步方法,當執行到方法內部的await時,會直接返回到調用方AccessTheWebAsync,也就是當前方法,因此就能夠在GetStringAsync方法下調用不依賴GetStringAsync方法返回值的方法DoIndependentWork。
4,標記await的地方,是異步方法放回調用方的地方。注意這個地方!
string urlContents = await getStringTask;
當執行到這個地方時,異步方法AccessTheWebAsync會返回調用方。這裏沒有寫對方法AccessTheWebAsync的調用代碼。
假如你在某個地方調用它的話你能夠調試看一看,方法AccessTheWebAsync是否是還沒執行完,就已經返回了。
以上讓人主要到幾點:
1,在一個方法的返回類型前加關鍵字async;
2,把方法名,命名爲以Async結尾,方便人一眼認出這是個異步方法(由於慣例);
3,在方法內耗時調用前加上await關鍵字,而後執行到該處時,程序直接返回到當前方法的外部調用處,讓調用處下面代碼能夠繼續執行,噹噹前方法耗時任務完成時,程序再返回到await處繼續向下執行,而後執行完畢該異步方法(執行完,程序會轉到跳進來的地方,這個到底怎麼保證,就須要額外研究了……)。
藍色地方可能很差理解,大概意思是這麼個意思:
static void Main(string[] args) { string inputStr=Console.ReadLine(); GetLongTimeConsumingQuery(inputStr) Console.WriteLine("查詢中……"); Console.ReadKey(); } public Async void GetLongTimeConsumingQuery(string inputStr) { //在指定文件夾下,從大量txt日誌文件中找到包含某個字符的錯誤日誌 Task<string> getStringTask=await QueryLog(inputStr) string logFileNames = await getStringTask; Console.WriteLine("你查詢的關鍵字在如下日誌中"+logFileNames+"出現!"); Console.WriteLine("感謝使用程序結束!"); }
執行到方法GetLongTimeConsumingQuery內的await處,方法會返回到Main方法,調用處而後向下執行輸出「查詢中……」
當QueryLog方法執行完畢後,程序會跳轉到await處繼續向下執行。