欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

介紹.net 4.5 異步編程核心內容,如何使用Async

系統 1833 0

通過使用異步編程,可避免出現性能瓶頸,并提高應用程序的整體響應。然而,技術編寫異步應用程序的傳統方法過于復雜,這使得異步程序難以編寫,調試和維護。

Visual Studio2012引入了一個簡單的開發方法,異步編程,我們可以充分利用.NET Framework 4.5 和 Windows Runtime中對異步的支持。這項復雜的工作將會交由編譯器來搞定,開發人員就像是在使用同步代碼來編寫應用程序的邏輯結構,但其結果是,得到了所有異 步編程的優點,但只要付出一點點工作。

本主題簡要介紹何時以及如何使用異步編程,其中包括支持說明本主題的例子。 由此下載VS2012.

異步提高響應能力

異步性必不可少,因為現實中有很多潛在的,可阻塞應用程序響應的情況,如當你的應用程序訪問網絡,文件系統等等。比如訪問Web資源,有時是緩慢的 或者是有延遲的。同步處理的話,如果有這樣的一個阻塞產生,那么整個應用程序就必須等待。而在一個異步的過程中,應用程序可以先繼續進行其他不依賴于網絡 的工作,直到所有可能產生阻塞的任務完成后再處理這些任務。

下表顯示了典型的可以通過異步編程提高響應的場景。列出的.NET Framework4.5和Windows Runtime的API包含支持異步編程的方法。

應用領域 支持異步方法的API
訪問Web

HttpClient , SyndicationClient

使用文件

StorageFile , StreamWriter , StreamReader , XmlReader

使用圖像

MediaCapture , BitmapEncoder , BitmapDecoder

WCF程序開發

Synchronous and Asynchronous Operations

使用sockets

Socket

異步性已經被證明對所有通過一個線程訪問UI,或是處理UI相關的活動的應用都特別的有價值。如果在同步的應用程序中任何一個處理過程被阻塞,那就意味著所有的東西都被阻塞了。你的應用程將會停止響應,更糟糕的是你可能會得出這樣的結論,這只是等待并不是失敗。

當你使用異步方法,應用程序將繼續響應的UI。您可以調整大小或最小化窗口,例如,當你不想等下去的時候,你可以關閉該應用程序。

現在這種基于異步的方法在你設計異步操作時,就像一組可以選擇的自動變速器,也就是說,你可以得到所有之前異步編程的好處,而不必像之前那樣苦逼(太讓人興奮了)。

異步方法現在很容易編寫

Async和Await關鍵字是C#異步編程的核心。通過使用這兩個關鍵字,你可以使用.NET Framework或Windows Runtime的資源創建一個異步方法如同你創建一個同步的方法一樣容易。通過使用async和await定義的異步方法,這里被稱為異步方法。

下面的例子顯示了一個異步方法。代碼中的幾乎所有的東西你看起來應該非常熟悉。注釋中描述了你為實現異步操作添加什么功能。

1 // 在簽名中三個要注意的事項:
2 // -該方法具有一個async修飾符.
3 // -返回類型為TaskorTask<t>.(參考"返回類型"一節.)
4 // 這里,返回值是Task<int>因為返回的是一個整數類型.
5 // -這個方法的名稱以"Async"結尾.
6 asyncTask< int >AccessTheWebAsync()
7 {
8 // 你需要添加System.Net.Http的引用來聲明client
9 HttpClientclient= new HttpClient();
10
11 // GetStringAsync返回Task<string>.這意味著當Task結束等待之后
12 // 你將得到一個string(urlContents).
13 Task< string >getStringTask=client.GetStringAsync( " http://msdn.microsoft.com " );
14
15 // 你可以做一些不依賴于GetStringAsync返回值的操作.
16 DoIndependentWork();
17
18 // await操作掛起了當前方法AccessTheWebAsync.
19 // -AccessTheWebAsync直到getStringTask完成后才會繼續.
20 // -同時,控制權將返回AccessTheWebAsync的調用者.
21 // -控制權會在getStringTask完成后歸還到AccessTheAsync.
22 // -await操作將取回getStringTask中返回的string結果.
23 string urlContents=awaitgetStringTask;
24
25 // return語句用來指定一個整數結果。
26 // 調用AccessTheWebAsync將會收到一個返回值的長度.
27 return urlContents.Length;
28 }

如果AccessTheWebAsync沒有什么不依賴于GetStringAsync的內容,也可以直接調用如下代碼:

string urlContents=awaitclient.GetStringAsync();

以下幾個特點總結了一下前面的例子中的異步方法。

  • 方法中包含了 async 修飾符。
  • 一個async方法按照慣例以“Async”結尾。
  • 返回類型是如下類型之一:
    • Task<TResult> 當你的方法有返回值時,TResult即返回值的類型
    • Task 當你的方法沒有return語句,或者返回值并不參與任何形式的運算(包括賦值操作)。
    • Void 當你編寫一個異步事件處理時會用到
  • 方法通常包括至少一個await的表達式,這意味著該方法在遇到await時不能繼續執行,直到等待異步操作完成。在此期間,該方法將被暫停,并且控制權返回到該方法的調用者。本主題接下來的部分說明了懸掛點后會發生什么。

在異步方法中,我們使用這些已經提供的關鍵字和類型來表達想要做什么的時候,編譯器并沒有閑著,他將處理包括跟蹤在暫停方法中控制權返回到 await點后將會如何處理。一些常規流程,如循環和異常處理,在之前的異步代碼中都比較難以處理。而現在都歸結到了一個async方法中,你會感覺你在 寫一個同步的代碼,之前的那些困惑已經不復存在了。

在異步方法中發生了什么

了解異步編程最重要的是理解控制權是如何在方法之間轉移的。下面的圖標將會解釋這個過程。

跟蹤一個異步程序

圖中的數字對應于下面的步驟。

1. 一個事件的處理函數用await的方式調用了異步方法 AccessTheWebAsync。

2. AccessTheWebAsync 創建了一個 HttpClient 實例,并調用了異步方法 GetStringAsync 來以下載一個頁面并將內容以string的形式返回.

3. 在GetStringAsync中將會碰到一些讓進程掛起的事情。也許它必須等待一個網站下載完成或其他一些阻塞性的動作,為了避免阻塞資源,GetStringAsync把控制權移交給了它的調用者AccessTheWEbAsync。

GetStringAsync返回Task<TResult>泛型,例子中的TResult是string類 型,AccessTheWebAsync將任務交給了getStringTask變量。這個任務代表了一個正在調用GetStringAsync的過程, 與一個承諾,當工作完成時,最終將產生string返回值。

4. 由于getStringTask并沒有被(用await)等待著索取結果,so AccessTheWebAsync 可以繼續其他不依賴于GetStringAsync最終返回結果的其他任務。這些任務由一個同步方法DoIndenpendentWork代表。

5.DoIndenpendentWork是一個同步方法,將會以同步的方式執行他的工作,并將返回值返回給調用者。

6. AccessTheWebAsync下一步是希望計算已經下載下來的字符長度,但是如果沒有這個字符,這個希望也就破滅了。

因此,AccessTheWebAsync 使用了await關鍵字掛起了自己的線程,并將控制權移交到了AccessTheWebAsync的調用者。AccessTheWebAsync將會返回 一個Task<int>給調用函數。這個任務承諾會在結束是返回給調用者一個int型的返回值。

注意

如果GetStringAsync在AccessTheWebAsync 調用await之前就已經完成了,那么控制權將依然在AccessTheWebAsync中。這種掛起和等待的操作也是很消耗資源的,如果返回值在 await之前就已經得到了,AccessTheWebAsync沒必要非得在用等待的方法去得到最終的結果。

在調用方法(這里是一個event的處理函數)的內部,處理過程是疊加的,event的處理函數將會等待AccessTheWebAsync,而 AccessTheWebAsync在等待GetStringAsync,與此同時,調用函數依然可以執行不依賴于這些返回值的操作。

7. GetStringAsync計算并產生一個string結果。這個string結果可能不是按照你現在期望的方式直接返回給他的調用函數,相反,這個結 果保存在一個代表方法完成的任務中,getStringTask。await操作符將會從getStringTask中取回期望的結果。賦值語句將會把結 果交給urlContents。

8. 當AccessTheWebAsync獲得了這個字符串結果,我們可以繼續計算這個字符串的長度了。這樣AccessTheWebAsync的工作也完成了,等待中的event處理函數也可以繼續了。

如果你剛剛接觸異步編程,那應該花一分鐘來思考一下同步行為和異步行為的不同。同步方法在工作完成之后返回(步驟5),但是異步方法返回一個 task值在他工作被暫停的時候(步驟3,6).當異步方法完成了他的工作之后,task被標記為complete,工作的結果也保存在task之中。

異步的API方法

你可能會想知道在哪里可以找到,如GetStringAsync,支持異步編程的API方法。.NET Framework 4.5包含許多使用await和async工作的成員方法。識別這些方法很簡單,方法名都是以”Async”結尾的并且返回類型都是Task或者 Task<TResult>。例如,System.IO.Stream類包含的方法,如CopyToAsync,ReadAsync,及 WriteAsync的對應的同步方法是CopyTo,Read和Write。

線程

異步方法的目的是不阻塞操作。在async方法中, await任務在執行的過程中,并不會阻塞當前的線程,其余的方法可以繼續執行,控制權將會移交到async方法的調用者。

async和await關鍵字并不會創建額外的線程,async方法不會去請求多線程操作。真正創建線程的操作是由Task.Run()實現的,一個async方法并不是在他自己的線程上執行的,只有當方法被激活時,才會使用當前線程的上下文和處理時間。

async方法要比BackgroundWorker更實用,而且使用起來更簡單而且不用去過多的考慮競態沖突神馬的。async方法會將運行中的代碼依據某些算法進行合理的拆分,并傳遞給線程池,這也是BackgroundWorker不能比的。

Async和Await

如果需要使用async或者await指定一個異步方法,我們需要注意一下兩點:

  • 用async標記的異步方應該使用await關鍵子來制定掛起點。await操作符會告訴編譯器,這個async方放在完成之前,后面的代碼無法繼續執行,同時,控制權轉移到async方法的調用者。
  • 標記為async的方法,調用時應使用await。

一個async方法里通常包含一個或多個的對應的await操作符,但如果沒有await表達式也不會導致編譯錯誤。但如果調用一個async方 法,卻不使用await關鍵字來標記一個掛起點的話,程序將會忽略async關鍵字并以同步的方式執行。編譯器會對類似的問題發出警告。

async和await都是上下文關鍵字:更多的細節可以參考:

返回類型和參數

在.NET Framework編程中,一個async方法通常返回的類型是Task或者Task<TResult>。在異步方法中,await操作符作用于從另外一個異步方法返回的Task。

如果指定Task<TResult>為返回結果,那么這個方法必須包含return指定的TResult結果的語句。

如果使用Task作為返回值,那么這個方法應該不存在使用return語句返回結果的代碼,或者返回的結果不參與任何運算(包括賦值操作)。

1 // 明確指定Task<tresult>
2 asyncTask< int >TaskOfTResult_MethodAsync()
3 {
4 int hours;
5 // ...
6 // return一個整數作為結果.
7 return hours;
8 }
9
10 // 調用TaskOfTResult_MethodAsync
11 Task< int >returnedTaskTResult=TaskOfTResult_MethodAsync();
12 int intResult=awaitreturnedTaskTResult;
13 // 或者使用一條語句
14 int intResult=awaitTaskOfTResult_MethodAsync();
15
16
17 // 明確指定Task
18 asyncTaskTask_MethodAsync()
19 {
20 // ...
21 // 方法沒有任何return語句.
22 }
23
24 // 調用Task_MethodAsync
25 TaskreturnedTask=Task_MethodAsync();
26 awaitreturnedTask;
27 // 或者使用一條語句
28 awaitTask_MethodAsync();

每一個返回的task都代表一個正在執行的工作,task包裝的信息中包含了這個異步方法的執行時的狀態,最終的結果,或者處理過程中拋出的異常。

如果返回值為void,這種類型主要使用于定義事件處理。異步事件通常被認為是一系列異步操作的開始。使用void返回類型不需要await,而且調用void異步方法的函數不會捕獲方法拋出的異常。

另外,async方法不能使用ref或者out參數,但是可以調用含有這些參數的方法。

命名約定

按照約定,你應該在異步方法的名稱后面追加“Async”用以標記此方法。但是在event,基類和接口中不需要遵守約定,就像本文例子中event處理函數Button1_Click一樣。

相關主題

一個完整的例子

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
17 using System.Net.Http;
18
19 namespace AsyncFirstExample
20 {
21 public partial class MainWindow:Window
22 {
23 // 將event處理函數用async標記,這樣就可以在處理函數中使用await實現異步操作.
24 private async void StartButton_Click( object sender,RoutedEventArgse)
25 {
26 // 調用和await分離的方式.
27 // Task<int>getLengthTask=AccessTheWebAsync();
28 /// /在這里做一些其他的工作.
29 // intcontentLength=awaitgetLengthTask;
30
31 int contentLength=awaitAccessTheWebAsync();
32
33 resultsTextBox.Text+=
34 String.Format( " \r\nLengthofthedownloadedstring:{0}.\r\n " ,contentLength);
35 }
36
37
38 // 在簽名中三個要注意的事項:
39 // -該方法具有一個async修飾符.
40 // -返回類型為TaskorTask<t>.(參考"返回類型"一節.)
41 // 這里,返回值是Task<int>因為返回的是一個整數類型.
42 // -這個方法的名稱以"Async"結尾.
43 asyncTask< int >AccessTheWebAsync()
44 {
45 // 你需要添加System.Net.Http的引用來聲明client
46 HttpClientclient= new HttpClient();
47
48 // GetStringAsync返回Task<string>.這意味著當Task結束等待之后
49 // 你將得到一個string(urlContents).
50 Task< string >getStringTask=client.GetStringAsync( " http://msdn.microsoft.com " );
51
52 // 你可以做一些不依賴于GetStringAsync返回值的操作.
53 DoIndependentWork();
54
55 // await操作掛起了當前方法AccessTheWebAsync.
56 // -AccessTheWebAsync直到getStringTask完成后才會繼續.
57 // -同時,控制權將返回AccessTheWebAsync的調用者.
58 // -控制權會在getStringTask完成后歸還到AccessTheAsync.
59 // -await操作將取回getStringTask中返回的string結果.
60 string urlContents=awaitgetStringTask;
61
62 // return語句用來指定一個整數結果。
63 // 調用AccessTheWebAsync將會收到一個返回值的長度.
64 return urlContents.Length;
65 }
66
67
68 void DoIndependentWork()
69 {
70 resultsTextBox.Text+= " Working.......\r\n " ;
71 }
72 }
73 }
74
75 // 運行結果:
76
77 // Working.......
78
79 // Lengthofthedownloadedstring:41564.

介紹.net 4.5 異步編程核心內容,如何使用Async和Await進行異步編程


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: wwwav在线| 作爱视频免费观看 | 性强烈欧美一级毛片 | 国产尤物在线观看一区二区 | 国产亚洲欧洲国产综合一区 | 色老头久久网 | 久久99精品久久久久久秒播 | 久久影院一区二区三区 | 久久久中文字幕日本 | 国产a级网站 | 国产成人一区二区三区 | 91福利免费视频 | 成人精品在线观看 | www.久久色 | 欧美区在线播放 | 国产免费福利网站 | 亚洲在线免费观看 | 日韩在线观看视频一区 | 欧洲精品在线观看 | 富二代精品视频 | 国产欧美日韩在线 | 日韩系列| 国产成人综合一区二区三区 | 蜜臀AV性色A片在线观看 | 亚洲国产精品久久综合 | 欧美13videosex性极品 | 夜色成人网 | 久久亚洲精品国产一区 | 亚洲欧洲一区二区 | dy天堂| 中文字幕在线精品 | 最新国产视频 | 精品免费久久久久欧美亚一区 | 三级中文字幕 | 欧美经典剧情系列h版在线观看 | 夜夜摸天天操 | 午夜成人在线视频 | 亚洲国产精品久久久久秋霞蜜臀 | 新版天堂资源中文在线 | 涩涩色中文综合亚洲 | 五月色综合|