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

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

ASP.NET sync over async(異步中同步,什么鬼?)

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

asp.net sync over async(異步中同步,什么鬼?)

async/await 是我們在 ASP.NET 應用程序中,寫異步代碼最常用的兩個關鍵字,使用它倆,我們不需要考慮太多背后的東西,比如異步的原理等等,如果你的 ASP.NET 應用程序是異步到底的,包含數據庫訪問異步、網絡訪問異步、服務調用異步等等,那么恭喜你,你的應用程序是沒問題的,但有一種情況是,你的應用程序代碼比較老,是同步的,但現在你需要調用異步代碼,這該怎么辦呢?有人可能會說,很簡單啊,不是有個 .Result 嗎?但事實真的就這么簡單嗎?我們來探究下。

首先,放出幾篇經典文章:

  • async & await 的前世今生
  • 異步編程 In .NET(中文資料中,寫異步最棒的兩篇文章
  • HttpClient.GetAsync(…) never returns when using await/async
  • Don't Block on Async Code(下面測試中的第三種情況
  • Should I expose synchronous wrappers for asynchronous methods?(sync over async 透徹

上面文章的內容,我們后面會說。光看不練假把式,所以,如果真正要體會 sync over async,我們還需要自己動手進行測試:

  • 1. 異步調用使用 .Result,同步調用使用 .Result
  • 2. 異步調用使用 await,同步調用使用 Task.Run
  • 3. 異步調用使用 await,同步調用使用 .Result
  • 4. 異步調用使用 Task.Run,同步調用使用 .Result
  • 5. 異步調用使用 await .ConfigureAwait(true),同步調用使用 .Result
  • 6. 異步調用使用 await .ConfigureAwait(false),同步調用使用 .Result
  • 7. 異步調用使用 await,異步調用使用 await
  • 8. 測試總結

先說明一下,在測試代碼中,異步調用使用的是 HttpClient.GetAsync 方法,并且測試請求執行兩次,關于具體的分析,后面再進行說明。

1. 異步調用使用 .Result,同步調用使用 .Result

測試代碼:

[Route("")][HttpGet]public string Index(){    System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId1:" + Thread.CurrentThread.ManagedThreadId);    var result = Test();    System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId4:" + Thread.CurrentThread.ManagedThreadId);    return result;}public static string Test(){    System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId2:" + Thread.CurrentThread.ManagedThreadId);    using (var client = new HttpClient())    {        var response = client.GetAsync(url).Result;        System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId3:" + Thread.CurrentThread.ManagedThreadId);        return response.Content.ReadAsStringAsync().Result;    }}

輸出結果:

Thread.CurrentThread.ManagedThreadId1:13Thread.CurrentThread.ManagedThreadId2:13Thread.CurrentThread.ManagedThreadId3:13Thread.CurrentThread.ManagedThreadId4:13Thread.CurrentThread.ManagedThreadId1:6Thread.CurrentThread.ManagedThreadId2:6Thread.CurrentThread.ManagedThreadId3:6Thread.CurrentThread.ManagedThreadId4:6

簡單總結:同步代碼中調用異步,上面的測試代碼應該是我們最常寫的,為什么沒有出現線程阻塞,頁面卡死的情況呢?而且代碼中調用了 GetAsync,為什么請求線程只有一個?后面再說,我們接著測試。

2. 異步調用使用 await,同步調用使用 Task.Run

測試代碼:

[Route("")][HttpGet]public string Index(){    System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId1:" + Thread.CurrentThread.ManagedThreadId);    var result = Task.Run(() => Test2()).Result;    System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId4:" + Thread.CurrentThread.ManagedThreadId);    return result;}public static async Task<string> Test2(){    System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId2:" + Thread.CurrentThread.ManagedThreadId);    using (var client = new HttpClient())    {        var response = await client.GetAsync(url);        System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId3:" + Thread.CurrentThread.ManagedThreadId);        return await response.Content.ReadAsStringAsync();    }}

輸出結果:

Thread.CurrentThread.ManagedThreadId1:6Thread.CurrentThread.ManagedThreadId2:7Thread.CurrentThread.ManagedThreadId3:11Thread.CurrentThread.ManagedThreadId4:6Thread.CurrentThread.ManagedThreadId1:6Thread.CurrentThread.ManagedThreadId2:7Thread.CurrentThread.ManagedThreadId3:12Thread.CurrentThread.ManagedThreadId4:6

簡單總結:根據上面的輸出結果,我們發現,在一個請求過程中,總共會出現三個線程,一個是開始的請求線程,接著是 Task.Run 創建的一個線程,然后是異步方法中 await 等待的執行線程,需要注意的是,ManagedThreadId1 和 ManagedThreadId4 始終是一樣的。

3. 異步調用使用 await,同步調用使用 .Result

測試代碼:

[Route("")][HttpGet]public string Index(){    System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId1:" + Thread.CurrentThread.ManagedThreadId);    var result = Test3().Result;    System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId4:" + Thread.CurrentThread.ManagedThreadId);    return result;}public static async Task<string> Test3(){    System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId2:" + Thread.CurrentThread.ManagedThreadId);    using (var client = new HttpClient())    {        var response = await client.GetAsync(url);        System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId3:" + Thread.CurrentThread.ManagedThreadId);        return await response.Content.ReadAsStringAsync();    }}

輸出結果:

Thread.CurrentThread.ManagedThreadId1:5Thread.CurrentThread.ManagedThreadId2:5

簡單總結:首先,頁面是卡死狀態,ManagedThreadId3 并沒有輸出,也就是執行到 await client.GetAsync 的時候,線程就阻塞了。

4. 異步調用使用 Task.Run,同步調用使用 .Result

測試代碼:

[Route("")][HttpGet]public string Index(){    System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId1:" + Thread.CurrentThread.ManagedThreadId);    var result = Test4().Result;    System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId4:" + Thread.CurrentThread.ManagedThreadId);    return result;}public static async Task<string> Test4(){    System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId2:" + Thread.CurrentThread.ManagedThreadId);    return await Task.Run(() =>    {        Thread.Sleep(1000);        System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId3:" + Thread.CurrentThread.ManagedThreadId);        return "xishuai";    });}

輸出結果:

Thread.CurrentThread.ManagedThreadId1:6Thread.CurrentThread.ManagedThreadId2:6Thread.CurrentThread.ManagedThreadId3:7

簡單總結:和第三種情況一樣,頁面也是卡死狀態,但不同的是,ManagedThreadId3 是輸出的,測試它的主要目的是和第三種情況形成對比,以便了解 HttpClient.GetAsync 中到底是什么鬼?

5. 異步調用使用 await .ConfigureAwait(true),同步調用使用 .Result

測試代碼:

[Route("")][HttpGet]public string Index(){    System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId1:" + Thread.CurrentThread.ManagedThreadId);    var result = Test5().Result;    System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId4:" + Thread.CurrentThread.ManagedThreadId);    return result;}public static async Task<string> Test5(){    System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId2:" + Thread.CurrentThread.ManagedThreadId);    using (var client = new HttpClient())    {        var task = client.GetAsync(url);        var response = await task.ConfigureAwait(true);        System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId3:" + Thread.CurrentThread.ManagedThreadId);        return await response.Content.ReadAsStringAsync();    }}

輸出結果:

Thread.CurrentThread.ManagedThreadId1:6Thread.CurrentThread.ManagedThreadId2:6

簡單總結:和上面兩種情況一樣,頁面也是卡死狀態,它的效果和第三種完全一樣,ManagedThreadId3 都沒有輸出的。

6. 異步調用使用 await .ConfigureAwait(false),同步調用使用 .Result

測試代碼:

[Route("")][HttpGet]public string Index(){    System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId1:" + Thread.CurrentThread.ManagedThreadId);    var result = Test6().Result;    System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId4:" + Thread.CurrentThread.ManagedThreadId);    return result;}publ
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲激情在线观看| 亚洲性视频网站| 国产精品一二三在线| 久久视频在线观看免费| www.欧美视频| 亚洲精品视频免费在线观看| 久久中文字幕视频| 成人激情电影一区二区| 国产精品v片在线观看不卡| 久久97精品久久久久久久不卡| 亚洲级视频在线观看免费1级| 亚洲最大福利视频网| 欧美日韩美女在线| 亚洲激情在线观看| 欧美激情免费在线| 日韩精品小视频| 欧美在线一级va免费观看| 日韩精品高清视频| 一本一本久久a久久精品综合小说| 欧美国产日韩精品| 欧美激情第1页| 精品在线观看国产| 日韩中文字幕第一页| 亚洲精品成人免费| 欧美激情综合色| 91福利视频网| 日韩视频在线一区| 国产一区二区三区在线观看视频| 久久免费观看视频| 国产精品视频公开费视频| 高跟丝袜一区二区三区| 欧美日韩国产成人| 91九色国产视频| 91在线视频成人| 亚洲精品网站在线播放gif| 久久久在线免费观看| 不卡在线观看电视剧完整版| 国产91在线播放九色快色| 亚洲国产精品久久久久秋霞不卡| 亚洲第一区在线| 亚洲黄一区二区| 亚洲人成网站在线播| 欧洲成人在线视频| 韩国国内大量揄拍精品视频| 欧美国产日韩视频| 国产精品久久色| 91沈先生作品| 国产精品欧美激情在线播放| 国产精品999| 久久精品电影网| 亚洲2020天天堂在线观看| 亚洲级视频在线观看免费1级| 亚洲人成伊人成综合网久久久| 欧美肥老太性生活视频| 国产亚洲精品激情久久| 久久精品国产亚洲一区二区| 久操成人在线视频| 欧美精品videosex性欧美| 欧美黑人xxxⅹ高潮交| 精品久久久久久电影| 国产不卡一区二区在线播放| 精品久久久久久久大神国产| 久久久爽爽爽美女图片| 国产精品综合久久久| 日本成人免费在线| 日韩国产欧美区| 国产精品久久久久久久久免费看| 欧美国产视频日韩| 久久激情视频免费观看| 久久人人爽人人爽人人片av高清| 久久视频在线观看免费| 在线观看国产欧美| 97精品一区二区三区| 久久人人97超碰精品888| 97超视频免费观看| 91精品视频一区| 日本精品va在线观看| 91高清免费在线观看| 国产亚洲aⅴaaaaaa毛片| 欧美激情欧美激情| 日韩成人在线观看| 中文在线资源观看视频网站免费不卡| 亲爱的老师9免费观看全集电视剧| 欧美一乱一性一交一视频| 中文字幕欧美亚洲| 91最新在线免费观看| 日韩在线观看免费全| 国产91精品最新在线播放| 成人激情春色网| 欧美尤物巨大精品爽| 92版电视剧仙鹤神针在线观看| 亚洲第一中文字幕在线观看| 国产91久久婷婷一区二区| 欧美精品福利在线| 国产精品永久免费在线| 国产精品直播网红| 国产综合在线观看视频| 国产裸体写真av一区二区| 久久91超碰青草是什么| 亚洲开心激情网| 日韩欧美国产一区二区| 亚洲深夜福利视频| 国语自产精品视频在线看抢先版图片| 国产精品美女在线| 成人xxxx视频| 免费不卡欧美自拍视频| 亚洲午夜性刺激影院| 97**国产露脸精品国产| 黑人精品xxx一区| 最好看的2019年中文视频| 亚洲天堂日韩电影| 日日噜噜噜夜夜爽亚洲精品| 欧美日韩国产成人| 亚洲欧美成人在线| 国产精品久久久久久久久粉嫩av| 国产精品久久久久久久9999| 亚洲成人激情图| 91日本视频在线| 亚洲免费视频在线观看| 国语自产精品视频在线看一大j8| 成人黄色影片在线| 久久久精品在线| 91爱视频在线| 国产精品自产拍在线观看中文| 粗暴蹂躏中文一区二区三区| 91高清视频免费| 91免费版网站入口| 国产做受高潮69| 亚州欧美日韩中文视频| 亚洲国产精品热久久| 人体精品一二三区| 午夜欧美不卡精品aaaaa| 国产精品欧美在线| 欧美成人在线影院| 疯狂做受xxxx高潮欧美日本| 影音先锋欧美在线资源| 久久中文久久字幕| 国产精品夫妻激情| 成人免费网站在线观看| 久久人人97超碰精品888| 精品伊人久久97| 日韩电影中文字幕一区| 亚洲精品之草原avav久久| 欧美日韩精品在线观看| 高清日韩电视剧大全免费播放在线观看| 亚洲自拍偷拍区| 久久久精品影院| 国产精品一区av| 国产亚洲美女精品久久久| 国产精品久久久久久久久借妻| 欧美与黑人午夜性猛交久久久| 尤物99国产成人精品视频| 日韩精品在线观看一区| 91色琪琪电影亚洲精品久久| xxx一区二区| 欧美不卡视频一区发布| 日本精品久久电影| 久久国产精品久久精品| 96精品视频在线| 国产v综合v亚洲欧美久久| 欧美成人午夜免费视在线看片| 中文字幕亚洲欧美日韩在线不卡| 精品国产欧美成人夜夜嗨| 91国自产精品中文字幕亚洲|