麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

使用Async和Await進行異步編程(C#版適用于VS2015)

2019-11-14 13:57:21
字體:
來源:轉載
供稿:網友

你可以使用異步編程來避免你的應用程序的性能瓶頸并且加強總體的響應。然而,用傳統的技術來寫異步應用是復雜的,同時編寫,調試和維護都很困難。

VS2012介紹了簡單的方法,那就是異步編程,它在.Net Framework 4.5和Windows 運行時提供了異步支持。編譯器做了開發者以前做的困難的工作,而且你的應用保持了類似于異步代碼的邏輯結構。結果,你輕易地就獲得了所有異步編程的優勢。

 

異步提升響應

異步對于可能阻塞的活動是至關重要的。例如當你的應用訪問Web的時候,訪問web資源有時有點慢或者延時,如果這樣一個活動在同步進程中阻塞了,整個應用就必須等待。在異步進程中,此應用可以繼續其他的工作,而不依賴于web資源直到這個可能阻塞的任務完成。

下表展示了異步編程提升響應的典型領域。陳列的來自Framework 4.5 和the Windows Runtime 的APIs包含了支持async編程的方法。

應用領域包含異步方法的APIs
Web 訪問HttpClient, SyndicationClient
處理文件StorageFile, StreamWriter, StreamReader, xmlReader
處理圖片MediaCapture, BitmapEncoder, BitmapDecoder
WCF編程Synchronous and Asynchronous Operations

 

 

 

 

 

對于訪問UI線程的應用,異步被證明是特別有價值的,因為所有Ui相關的活動通常共享一個線程。如果同步應用的任何一個進程被阻塞了,那么所有進程都被阻塞了。屆時你的應用停止了響應,你可能推斷它出錯了,然而它卻僅僅在等待。

當你使用異步方法的時候,應用會繼續響應UI。你可以調整或者最小化窗口,或者如果你不想等待應用完成,那就關了它。

基于異步的方法相當于在設計異步操作時,向可供你選擇的選項增加了自動的傳輸裝置。那就是說,你以更少的付出卻獲得了所有傳統異步編程的好處。

異步方法更容易編寫

關鍵字async和await是異步編程的核心。通過使用這兩個關鍵字,可以使用.NET Framework 或者Windows Runtime的資源來創建異步方法,這就像創建同步方法一樣簡單。使用await和async定義的方法為異步方法。

 

下面是一個異步方法的例子。代碼中的所有你都應該看著很熟悉。

// 簽名中需要注意的三件事://  -方法有一個async修飾符. //  - 返回值是 Task 或 Task<T>. //    這里返回一個Task<int>,因為return語句返回int類型//  - 方法名以 "Async"結尾。async Task<int> accessTheWebAsync(){     // 先要添加 System.Net.Http引用來聲明 client.    HttpClient client = new HttpClient();    // GetStringAsync 返回 Task<string>. 這意味著當你等待這個任務的時候,你將獲得一個字符串(urlContents)。    Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");    //這里你可以處理任務,它不依賴來自GetStringAsync的字符串    DoIndependentWork();    // await 操作符延緩了AccessTheWebAsync.    //  - AccessTheWebAsync 直到 getStringTask完成才繼續執行。    //  - 同時, 控制返回到 AccessTheWebAsync的調用者.    //  - 當getStringTask完成時,控制恢復.     //  - await 操作符然后檢索來自 getStringTask的字符串.    string urlContents = await getStringTask;    //  return 語句表明返回一個整數.    return urlContents.Length;}

如果AccessTheWebAsync在調用GetStringAsync 和等待完成之間沒有其他要處理的代碼,可以用下面一條單句簡化代碼。

string urlContents = await client.GetStringAsync();

下面總結了一些上面的異步方法的例子的特點:

  • 方法簽名包括async修飾符
  • 異步方法的命名,按照慣例,以“Async”后綴結尾
  • 返回類型只能是這三種:Task<TResult>,Task或void
  • 方法通常至少包括一個await表達式,await標記了一個點,這個點就是直到異步操作完成后異步方法才繼續執行。同時,方法是延遲的,控制返回到方法的調用者。

異步方法中發生什么?

理解異步編程最重要的事情是 控制流如何從一個方法移動到另一個方法。下圖帶你理解這個過程。

對應數字序號的解釋如下:

 

  1. 事件句柄調用并等待AccessTheWebAsync 異步方法。
  2. AccessTheWebAsync 創建一個HttpClient實例,并調用GetStringAsync異步方法來下載website的內容,保存到字符串。
  3. GetStringAsync發生了一些事情,延遲了方法的進度。也許必須等待站點下載或者一些其他的阻塞活動。為避免阻塞資源,GetStringAsync轉讓控制權給它的調用者AccessTheWebAsync 。
  4. 因為getStringTask還沒有被await,所以AccessTheWebAsync 可以不依賴GetStringAsync返回的最終結果繼續工作。這項工作是一個同步方法DoIndependentWork。
  5. DoIndependentWork是一個處理一些事情的同步方法,并且返回給它的調用者。
  6. AccessTheWebAsync 已經完成了它能做的事情,但getStringTask還沒有返回結果。AccessTheWebAsync 下一步想要計算并返回已經下載的字符串的長度,但是該方法直到有字符串時才能計算那個值。
    因此,AccessTheWebAsync 使用了一個await操作符來延遲它的進度,并且轉讓控制權給調用AccessTheWebAsync 的方法。AccessTheWebAsync 返回一個Task<int>給調用者。這個task代表一種產生一個整數結果的允諾,這個整數結果就是下載字符串的長度。
    【注意:如果GetStringAsync(并且從而getStringTask)在AccessTheWebAsync等待它之前完成,那么控制權保留在AccessTheWebAsync中。如果調用的異步過程(getStringTask)已經完成了,延遲和后來返回到AccessTheWebAsync的代價將會被浪費,因而AccessTheWebAsync沒必要等待最終的結果了。】
    在調用者內部(這個例子中的事件句柄),處理模式繼續執行。在等待異步返回的結果之前,調用者可能處理其他的工作而不依賴來自AccessTheWebAsync的結果,或者調用者可能會立即等待。事件句柄等待AccessTheWebAsync,AccessTheWebAsync等待GetStringAsync。
  7. GetStringAsync完成并產生了字符串結果。這個字符串結果可能沒有按你期望的那樣通過GetStringAsync的調用被返回。(記住步驟3中該方法已經返回了一個task。)相反,這個字符串被保存到代表這個方法完成的任務對象getStringTask中。Await操作符檢索來自getStringTask的結果。賦值語句將檢索的結果賦值給urlContent變量。
  8. 當AccessTheWebAsync獲得字符串結果時,該方法可以計算這個字符串的長度。然后AccessTheWebAsync的工作也完成了,等待中的事件句柄可以恢復了。

API異步方法

你可能想知道在哪里找到支持異步的像GetStringAsync的方法。.NET Framework 4.5包含了許多對async和await有效的成員。你可以通過“Async”后綴和Task或Task<TResult>的返回類型來識別這些成員。比如,System.IO.Stream類中,在同步方法CopyTo, Read和 Write的旁邊包含了很多像CopyToAsync, ReadAsync和WriteAsync的方法。

線程

async方法規定為非阻塞操作。當等待的task運行的時候,async方法的await表達式不會阻塞當前線程。相反,該表達式注冊當前方法的剩余作為延續,并且返回控制權給async方法的調用者。

async和await關鍵字不會造成額外的線程被創建。async方法不會要求多線程是因為async方法沒有運行在它自己的線程上。該方法運行在當前的同步上下文上,只有該方法激活的時候才會在該線程上使用時間。你可以使用Task.Run()來將CPU受限的工作移動到后臺線程中,但是后臺線程不會幫助處理僅僅等待結果變成可利用的。

異步和等待  

可以查看我的這篇博客Async and Await 異步和等待。

返回類型和參數

請查看我的這篇博客Async and Await 異步和等待。

命名慣例

按照慣例,給方法添加async修飾符,給方法名追加“Async”后綴。

復雜案例

下面的代碼來自WPF應用的MainWindow.xaml.cs。

 

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;// 添加 System.Net.Http的using指令和引用;using System.Net.Http;namespace AsyncFirstExample{    public partial class MainWindow : Window    {        // 給事件句柄添加 async標記,為的是可在方法體內使用 await .        PRivate async void StartButton_Click(object sender, RoutedEventArgs e)        {            // 分別調用和await.            //Task<int> getLengthTask = AccessTheWebAsync();            //// 可以在這里做一些獨立的工作.            //int contentLength = await getLengthTask;            int contentLength = await AccessTheWebAsync();            resultsTextBox.Text +=                String.Format("/r/nLength of the downloaded string: {0}./r/n", contentLength);        }        // 簽名中需要注意的三件事:        //  -方法有一個async修飾符.         //  - 返回值是 Task 或 Task<T>.         //    這里返回一個Task<int>,因為return語句返回int類型        //  - 方法名以 "Async"結尾。        async Task<int> AccessTheWebAsync()        {             // 先要添加 System.Net.Http引用來聲明 client.            HttpClient client = new HttpClient();            // GetStringAsync 返回 Task<string>. 這意味著當你等待這個任務的時候,你將獲得一個字符串(urlContents)。            Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");            //這里你可以處理任務,它不依賴來自GetStringAsync的字符串            DoIndependentWork();            // await 操作符延緩了AccessTheWebAsync.            //  - AccessTheWebAsync 直到 getStringTask完成才繼續執行。            //  - 同時, 控制返回到 AccessTheWebAsync的調用者.            //  - 當getStringTask完成時,控制恢復.             //  - await 操作符然后檢索來自 getStringTask的字符串.            string urlContents = await getStringTask;            //  return 語句表明返回一個整數.            return urlContents.Length;        }        void DoIndependentWork()        {            resultsTextBox.Text += "Working . . . . . . ./r/n";        }    }}

 


 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 99精品国产一区二区三区 | 国产91丝袜在线播放 | 国产美女的小嫩bbb图片 | 日韩欧美精品电影 | 激情在线视频 | 伊人二本二区 | 午夜影视一区二区 | 成人做爰高潮片免费视频韩国 | 精品一区二区三区免费毛片 | 久久国产精品久久久久 | 日日草夜夜操 | 国产一区二区三区四区精 | 男人午夜小视频 | 97中文字幕第一一一页 | 中文字幕视频在线播放 | 一级片九九 | 好吊一区二区三区 | 特片网久久 | 北京一级毛片 | 久久伊人国产精品 | 91成人免费电影 | 久久精品中文字幕 | 亚洲国产二区 | 日韩字幕| 国产精品午夜性视频 | 激情视频日韩 | 91福利社在线 | 日本在线播放一区二区三区 | 欧美一级美国一级 | 国产精品av久久久久久网址 | 成人444kkkk在线观看 | 久久久久久中文字幕 | 国产免费一区二区三区在线能观看 | 成人av一二三区 | 激情夜色 | 九九热视频免费在线观看 | 国产精品免费看 | 国产a一级片 | 黄色片网站在线免费观看 | 99精品视频网站 | 成人勉费视频 |