亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

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

await之后的線程問題

2019-11-17 02:56:27
字體:
來源:轉載
供稿:網友

await之后的線程問題

之前看了園子里的一篇文章「async & await的前世今生」,收益頗多。而其中有句話被博主特意用紅色標注,所以留意多看了幾眼,「await 之后不會開啟新的線程(await 從來不會開啟新的線程)」。在MSDN上找到的相關資料也佐證了其正確性——The async and await keyWords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active.(async 和 await 關鍵字不會導致創建其他線程。 因為異步方法不會在其自身線程上運行,因此它不需要多線程。 只有當方法處于活動狀態時,該方法將在當前同步上下文中運行并使用線程上的時間。)

再建立一個Windows Forms應用工程,寫點代碼更形象地說明問題:

PRivate void Form1_Load(object sender, EventArgs e){    PrintDataAsync();    Debug.Print("three");}private async void PrintDataAsync(){    Task<int> result = CalculateDataAsync();    Debug.Print("second");    int data = await result;    Debug.Print("last:" + data);}private async Task<int> CalculateDataAsync(){    Debug.Print(string.Format("{0} : {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));    Debug.Print("first");    int result = 0;    for (int i = 0; i < 10; i++)    {        result += i;    }    await Task.Delay(1000);    Debug.Print("four");    Debug.Print(string.Format("{0} : {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));    return result;};

程序的結果如預期的一樣,Output窗口中可以看到以下內容:

8 : Falsefirstsecondthreefour8 : Falselast:45

await之前的ManagedThreadId值與之后的ManagedThreadId值一致,IsThreadPoolThread始終是False,說明當前線程沒有發生改變,也沒有產生新的線程。

但如果建立的是Console應用工程,結果就不同了。

static void Main(string[] args){    PrintDataAsync();    Console.WriteLine("three");    Console.Read();}private static async void PrintDataAsync(){    Task<int> result = CalculateDataAsync();    Console.WriteLine("second");    int data = await result;    Console.WriteLine("last:" + data);}private static async Task<int> CalculateDataAsync(){    Console.WriteLine(string.Format("{0} : {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));    Console.WriteLine("first");    int result = 0;    for (int i = 0; i < 10; i++)    {        result += i;    }    await Task.Delay(1000);    Console.WriteLine("four");    Console.WriteLine(string.Format("{0} : {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));    return result;}

這段代碼的執行結果:

8 : Falsefirstsecondthreefour10 : Truelast:45

ManagedThreadId在await之后發生了變化,IsThreadPoolThread也變為了True,說明不是同一個線程。

為什么會這樣?再看一下MSDN中描述——「The method runs on the current synchronization context and uses time on the thread only when the method is active」,這里涉及到SynchronizationContext對象的使用。

在Windows Forms工程代碼中加入Debug.Print(SynchronizationContext.Current.ToString()); 檢測代碼,其輸出是System.Windows.Forms.WindowsFormsSynchronizationContext。

而如果在Console工程中加入類似的檢測代碼Console.WriteLine(SynchronizationContext.Current.ToString()); 則會拋出空引用異常,因為SynchronizationContext.Current在Console工程中的值為null。

又從MSDN Magazine找到SynchronizationContext相關的文章,其中有介紹到:By convention, if a thread’s current SynchronizationContext is null, then it implicitly has a default SynchronizationContext.(根據慣例,如果一個線程的當前 SynchronizationContext 為 null,那么它隱式具有一個默認 SynchronizationContext。)The default SynchronizationContext is applied to ThreadPool threads unless the code is hosted by asp.net.(默認 SynchronizationContext 應用于 ThreadPool 線程,除非代碼由 ASP.NET 承載。)

這里提到了APS.NET,所以再建個Web Forms應用工程用于驗證:

protected void Page_Load(object sender, EventArgs e){    PrintDataAsync();    Debug.Print("three");}private async void PrintDataAsync(){    Debug.Print(SynchronizationContext.Current.ToString());    Task<int> result = CalculateDataAsync();    Debug.Print("second");    int data = await result;    Debug.Print("last:" + data);}private async Task<int> CalculateDataAsync(){    Debug.Print(string.Format("{0} : {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));    Debug.Print("first");    int result = 0;    for (int i = 0; i < 10; i++)    {        result += i;    }    await Task.Delay(1000);    Debug.Print("four");    Debug.Print(string.Format("{0} : {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));    return result;}

輸出結果:

System.Web.AspNetSynchronizationContext8 : Truefirstsecondthreefour9 : Truelast:45

ManagedThreadId值發生改變,IsThreadPoolThread始終是True,SynchronizationContext.Current值為System.Web.AspNetSynchronizationContext。

由三次試驗及相關資料可以得出結論,await之后的線程依據SynchronizationContext在不同環境中的不同定義而產生不同的結果。所以「await 之后不會開啟新的線程(await 從來不會開啟新的線程)」的肯定句式改成「await 之后會開啟新的線程嗎? Maybe」這樣的句式更加合適些。

最后補充一點,若是把第一個Windows Forms工程的代碼await Task.Delay(1000);改成await Task.Delay(1000).ConfigureAwait(false); 的話,則可以得到第二個Console工程同樣的結果。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
96sao精品视频在线观看| 欧美夜福利tv在线| 日韩亚洲欧美成人| 8x海外华人永久免费日韩内陆视频| 国产精品中文字幕久久久| 国产精品2018| 国产91精品高潮白浆喷水| 中文字幕一区日韩电影| 亚洲第一偷拍网| 久久成人精品一区二区三区| 久久影视电视剧免费网站清宫辞电视| 日韩av网站在线| 亚洲精品一区在线观看香蕉| 国产精品久久999| 国产精品欧美激情| 欧美极品少妇xxxxⅹ免费视频| 欧美成年人在线观看| 久久久久久国产精品| 国产成人在线一区| 日韩精品在线视频美女| 中文日韩电影网站| 欧美性高跟鞋xxxxhd| 久久综合久中文字幕青草| 在线日韩欧美视频| 欧美一区深夜视频| 91中文精品字幕在线视频| 日韩在线观看免费全集电视剧网站| 美女撒尿一区二区三区| 国产va免费精品高清在线| 欧美夫妻性生活视频| 性欧美视频videos6一9| 成人网中文字幕| 日韩高清电影免费观看完整版| 91麻豆国产精品| 亚洲国产精品一区二区久| 久久91精品国产91久久跳| 成人妇女免费播放久久久| 精品亚洲夜色av98在线观看| 国产亚洲欧洲高清一区| 伦伦影院午夜日韩欧美限制| 91网站在线免费观看| 亚洲va欧美va国产综合剧情| 中文字幕日韩综合av| 亚洲另类欧美自拍| 97在线观看免费| 国产精品久久久91| 日本精品免费一区二区三区| 国产亚洲精品日韩| 国产成人精品一区二区三区| 日韩精品极品在线观看| 欧美日韩中文字幕综合视频| 欧美亚洲激情视频| 日韩av在线高清| 久久久久久噜噜噜久久久精品| 日韩欧美第一页| 欧美激情手机在线视频| 久久久久久美女| 亚洲精品久久久久久久久久久久| 欧美成人性生活| 91av视频在线| 57pao国产成人免费| 欧美激情精品久久久久| 久久久久久一区二区三区| 色综合91久久精品中文字幕| 日本欧美一二三区| 91精品国产色综合| 久久综合88中文色鬼| 夜夜嗨av一区二区三区四区| 中文字幕久热精品在线视频| 色樱桃影院亚洲精品影院| 国产日韩欧美中文| 国产精品99久久久久久久久久久久| 欧美电影《睫毛膏》| 成人精品视频久久久久| 亚洲va国产va天堂va久久| 精品无人区太爽高潮在线播放| 成人国产精品一区| 视频一区视频二区国产精品| 亚洲成av人片在线观看香蕉| 午夜剧场成人观在线视频免费观看| 91麻豆桃色免费看| 黑人巨大精品欧美一区二区一视频| 欧美激情在线有限公司| 亚洲第一网中文字幕| 51ⅴ精品国产91久久久久久| 国产精品自产拍在线观看中文| 欧美日韩国产成人在线观看| 国产精品自在线| 久久精品亚洲精品| 一区二区三区久久精品| 国产精品r级在线| 日韩精品在线免费观看视频| 国产国语videosex另类| 国产精品久久不能| 亚洲视频一区二区三区| 一区二区三区回区在观看免费视频| 日韩美女av在线免费观看| 欧美巨大黑人极品精男| 在线播放日韩精品| 91精品国产成人www| 成人黄色免费在线观看| 亚洲成人激情视频| 日韩av第一页| 亚洲黄页视频免费观看| 中文字幕亚洲综合久久筱田步美| 欧美日韩免费一区| 成人观看高清在线观看免费| 久久久av亚洲男天堂| 亚洲精品国偷自产在线99热| 欧美老女人www| 91精品国产自产在线观看永久| 性色av香蕉一区二区| 久久久久久久久久国产| 亚洲国产成人在线视频| 久久久久久久国产精品| 国产九九精品视频| 欧美成人性色生活仑片| 美女撒尿一区二区三区| 亚洲欧美日韩网| 国产亚洲精品美女久久久久| 97久久久久久| 亚洲一品av免费观看| 成人h片在线播放免费网站| 欧美日韩激情视频| 一区二区在线视频| 欧美日韩国产在线看| 日韩欧美亚洲范冰冰与中字| 91av福利视频| 欧美国产日产韩国视频| 日韩av中文字幕在线免费观看| 青草青草久热精品视频在线网站| 国产一区二中文字幕在线看| 91精品国产99| 亚洲人成毛片在线播放| 色综合久久精品亚洲国产| 国产手机视频精品| 日韩av在线免费观看| 色播久久人人爽人人爽人人片视av| 欧美成人高清视频| 国产成+人+综合+亚洲欧美丁香花| 久久九九免费视频| 一区二区三区视频免费在线观看| 富二代精品短视频| 成人妇女淫片aaaa视频| 日韩国产欧美精品在线| 这里精品视频免费| 久久九九免费视频| 中文字幕欧美日韩在线| 亚洲一品av免费观看| 亚洲国产精品一区二区久| 国产在线观看91精品一区| 91在线精品视频| 日韩视频免费中文字幕| 亚洲人成网7777777国产| 国产精国产精品| 精品毛片三在线观看| 日韩在线中文视频| 日韩av色综合| 亚洲成人aaa| 亚洲视频精品在线| 欧美激情极品视频| 欧美黄色小视频| www.欧美精品一二三区| 日韩在线观看免费高清完整版|