await和async再學習

 

 

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處繼續向下執行。

相關文章
相關標籤/搜索