標籤:ros ret pap 依賴 自己 返回 線程阻塞 target 線程
C# 5.0引入了兩個關鍵字 async和await,這兩個關鍵字在很大程度上協助我們簡化了非同步編程的實現代碼,而且TPL中的task與async和await有很大的關係
思考了一下非同步編程中的async & await關鍵字,對兩個關鍵字尤其是await關鍵字一直很迷糊,因此深入思考了一下。首先藉助的樣本是:
[你必須知道的非同步編程]C# 5.0 新特性——Async和Await使非同步編程更簡單
這是部落格園一個大牛寫的,自己也一直關注這個大神,不得不說,部落格園大神很多,而且氛圍也很好。我引入了其中的樣本:
private async void button1_Click(object sender, EventArgs e) { var length = AccessWebAsync(); // 這裡可以做一些不依賴回複的操作 OtherWork(); this.textBox1.Text += String.Format("\n 回複的位元組長度為: {0}.\r\n", await length); this.textBox2.Text = Thread.CurrentThread.ManagedThreadId.ToString(); } private async Task<long> AccessWebAsync() { MemoryStream content = new MemoryStream(); // 對MSDN發起一個Web請求 HttpWebRequest webRequest = WebRequest.Create("http://msdn.microsoft.com/zh-cn/") as HttpWebRequest; if (webRequest != null) { // 返回回複結果 using (WebResponse response = await webRequest.GetResponseAsync()) { using (Stream responseStream = response.GetResponseStream()) { await responseStream.CopyToAsync(content); } } } this.textBox3.Text = Thread.CurrentThread.ManagedThreadId.ToString(); return content.Length; } private void OtherWork() { this.textBox1.Text += "\r\n等待伺服器回複中.................\n"; }
async是同步執行程式,而await起到的則是劃分區段以及掛起調用方的作用,並不會建立新的線程,根據大神的分析:
在await關鍵字出現的前面部分代碼和後面部分代碼都是同步執行的(即在調用線程上執行的,也就是GUI線程,所以不存在跨線程訪問控制項的問題),await關鍵處的程式碼片段是線上程池線程上執行。
在上面的代碼中,調用了FCL封裝的GetResponseAsync等方法從而不阻塞當前UI線程,await的確不會建立新的線程,但是就在這裡而言,await運算式中的確建立了新的線程——GetResponseAsync所做的.以至於造成了表面同步的假象。我之前寫過一篇文章
C#async與await非同步編程學習筆記
await關鍵字與Task有莫大的關聯,從其特定的傳回值就可以看出來,更深層次的await與task的continuewith函數應該是等效的.因此,用async & await關鍵字實現非同步要麼調用FCL封裝好的非同步方法呼叫,要麼我們就自己調用task來建立新的線程分擔UI線程的任務以防止UI線程阻塞.
.net 非同步編程async & await關鍵字的思考