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

首頁 > 編程 > .NET > 正文

ASP.NET 謹用 async/await

2024-07-10 13:32:52
字體:
來源:轉載
供稿:網友

C# 5.0 引入 async/await 關鍵字,旨在簡化異步編程模型,拋去語法糖就是 Net4.0 的 Task + 狀態機。其實在處理異步編程使用 Task 還是挺簡單的,不過既然推出了新的語法糖,難免會嘗試一下,然而在使用中卻沒想象中那么單純。以下針對ASP.NET 應用程序實際使用過程中的一些總結, 包括 異常捕獲 、 死鎖 、 應用程序崩潰 ,實際使用過程中一不注意就可能掉坑里了。

異常捕獲

async 方法有三種返回類型: void、Task、Task

async void

該方式聲明的方法是無法使用 catch 捕獲異常的,所以以下代碼的 try、catch 并沒什么卵用。

private static async void ThrowExceptionAsync(){ await Task.Delay(1000); throw new Exception("拋個異常玩玩");}public static async void CatchAsyncVoidException(){ try {  ThrowExceptionAsync(); } catch (Exception ex) { throw ex; }}

async Task 或 async Task

這兩種方式聲明的方法異常信息會包含Task屬性內,但前提需要在try里面使用 await 等待。

private static async Task ThrowExceptionAsync(){ await Task.Delay(1000); throw new Exception("拋個異常玩玩");}public static async Task CatchAsyncTaskException(){ try {   await ThrowExceptionAsync(); } catch (Exception ex) { throw ex; }}TaskScheduler.UnobservedTaskException

未捕獲的 Task 異常信息可以通過設置全局的TaskScheduler.UnobservedTaskException 來記錄錯誤日志,在 Global.asax 增加如下代碼:

void Application_Start(object sender, EventArgs e){ // 在應用程序啟動時運行的代碼 TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskExceptionException;}void TaskScheduler_UnobservedTaskExceptionException(object sender, UnobservedTaskExceptionEventArgs e){ if (e.Exception != null) { // do something }}

同步上下文

異步編程必然是關于線程的使用,線程有一個同步上下文的概念,個人認為線程同步上下文是 async/await 遇到最揪心的問題。在現有項目開發中我們可能想嘗試使用 async/await,但老代碼都是同步方式,這時如果調用一個聲明為 async 的方法,死鎖和應用程序崩潰的問題一不小心就可能出現。

注意:控制臺程序和.Net Core程序 將不會遇到這個問題,它們不需要同步上下文。

死鎖

private static async Task XXXAsync(){ await Task.Delay(1000);  // some code}public static void Test(){ var task = XXXAsync(); task.Wait();}

以上代碼很完美的實現了死鎖。 默認情況下,當 Wait() 未完成的 Task 時,會捕獲當前線程上下文,在 Task 完成時使用該上下文恢復方法的執行。 當 async 方法內的 await 執行完成時,它會嘗試獲取調用者線程所在的上下文執行方法的剩余部分, 但是該上下文已含有一個線程,該線程在等待 async 方法完成。然后它們相互等待對方,然后就沒有然后了,死在那里。

針對死鎖問題的解決方式是增加 ConfigureAwait(false)

// await Task.Delay(1000);await Task.Delay(1000).ConfigureAwait(false); // 解決死鎖

當 await 等待完成時,它會嘗試在線程池上下文中執行 async 方法的剩余部分,因此就不存在死鎖。

應用程序崩潰

測試環境總發現IIS應用程序池總是崩潰,到底是什么原因?當時我們對這個問題也是非常懵逼,代碼看上去并沒什么明顯毛病,試圖欺騙自己應該是環境本身的問題吧,但事實上確實是在代碼中下了毒。通過各種資料查閱和測試,基本可以斷定是同步代碼調用異步代碼,同步上下文引起的問題。

如果調用一個 async 方法。如果使用 await 等待,當前線程立馬被釋放回線程池,線程的上下文信息會被保存。如果沒有使用 await(async void 的方法,必然沒有辦法使用 await),調用 async 方法之后,代碼會繼續往下執行,執行完成后當前線程被釋放回線程池,線程的上下文信息不會被保存。當 async 中的異步任務執行完成后,會從線程池中獲取一個線程繼續執行剩余代碼,同時會獲取當初調用者所在線程的上下文信息(如果當初調用者所在線程沒有釋放回線程池,上下文信息可以獲取到)。那么問題就來了,如果當初調用者沒有使用 await 并且 所在線程釋放回線程池了,上下文信息因為沒有被保持下來,就獲取不到了,這時候會拋出異常 未將對象引用設置到對象的實例 ,經過測試這個異常信息并不一定每次都會出現,原因和線程的釋放有關,調用者所在線程的上下文信息存在就不會拋出異常。異常錯誤信息如下,這個異常最終會導致應用程序集停止。

在 System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext)  在 System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext)  在 System.Web.LegacyAspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state)  在 System.Web.LegacyAspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state)  在 System.Web.LegacyAspNetSynchronizationContext.Post(SendOrPostCallback callback, Object state)  在 System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.PostAction(Object state)  在 System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback callback, Object state, Task& currentTask)--- 引發異常的上一位置中堆棧跟蹤的末尾 ---  在 System.Threading.Tasks.AwaitTaskContinuation.<>c.<ThrowAsyncIfNecessary>b__18_0(Object s)  在 System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)  在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)  在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)  在 System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()  在 System.Threading.ThreadPoolWorkQueue.Dispatch()  在 System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

針對以上異常我們有什么方式可以解決呢?依然是ConfigureAwait(false),在 Task 上加上 ConfigureAwait(false),此設置代表當 async 中的異步任務完成后,不讀取當時調用它的原線程的上下文信息,而是在線程池上下文中執行 async 方法的剩余部分。

public static Task XXXAsync(){ await Task.Run(() => { // some code }).ConfigureAwait(false);}

總結

以上所述是小編給大家介紹的ASP.NET 謹用 async/await,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VeVb武林網網站的支持!


注:相關教程知識閱讀請移步到ASP.NET教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
成人免费福利在线| 国产亚洲精品va在线观看| 91久久久久久| 国产精品高潮呻吟久久av野狼| 国产视频在线观看一区二区| 精品国产一区久久久| 国内免费精品永久在线视频| 亚洲国语精品自产拍在线观看| 精品在线观看国产| 91在线高清视频| 亚洲欧美制服丝袜| 亚洲人永久免费| 亚洲欧美日韩直播| 国产欧亚日韩视频| 欧美网站在线观看| 国产精品444| 国内精品久久久久| 国产精品国内视频| 日韩欧美主播在线| 高清日韩电视剧大全免费播放在线观看| 91在线直播亚洲| 国产精品激情av电影在线观看| 欧美福利小视频| 欧亚精品在线观看| 国产91成人在在线播放| 亚洲欧美在线x视频| 国产一区二区三区直播精品电影| 国产精品av免费在线观看| 欧美午夜精品久久久久久浪潮| 日韩电影免费观看中文字幕| 亚洲天堂网站在线观看视频| 日韩精品在线观看网站| 日韩av在线电影网| 国内精品美女av在线播放| 欧美性黄网官网| 精品中文字幕在线| 中文字幕亚洲欧美日韩高清| 欧美国产日韩一区二区三区| 狠狠躁天天躁日日躁欧美| 亚洲欧美国产制服动漫| 久久视频在线观看免费| 在线观看亚洲视频| 日韩在线免费视频观看| 国产精品大陆在线观看| 狠狠躁夜夜躁人人爽超碰91| 欧美午夜片在线免费观看| 日韩视频免费在线| 久久高清视频免费| 色狠狠久久aa北条麻妃| 69久久夜色精品国产69| 国产精品视频精品视频| 亚洲欧美日韩中文在线| 成人女保姆的销魂服务| 日日摸夜夜添一区| 日本在线观看天堂男亚洲| 97视频在线播放| 亚洲a成v人在线观看| www日韩中文字幕在线看| 色青青草原桃花久久综合| 高清亚洲成在人网站天堂| 欧美日韩国产一区二区| 欧美俄罗斯性视频| 中文字幕免费精品一区高清| 久久影视电视剧凤归四时歌| 国产精品羞羞答答| 日韩美女免费线视频| 国产精品美乳一区二区免费| 欧美日韩免费网站| 午夜精品www| 成人国产在线激情| 久久精品视频va| 国产精品九九九| 亚洲v日韩v综合v精品v| 91精品久久久久久久久久久久久| 日韩免费观看网站| 欧美激情在线视频二区| 国产亚洲精品久久久久久| 国产亚洲欧洲在线| 欧美亚洲在线播放| 欧美国产视频日韩| 日韩中文字幕在线观看| 视频在线观看一区二区| 成人xxxxx| 亚洲一区二区免费在线| 91精品国产91久久久久福利| 91亚洲精品一区二区| 欧美精品videosex极品1| 欧美成人精品一区二区| 亚洲大胆美女视频| 国产日韩欧美中文在线播放| 亚洲电影免费观看| 亚洲精品自产拍| 人体精品一二三区| 国语自产偷拍精品视频偷| 久久频这里精品99香蕉| 亚洲美女视频网站| 欧美老女人性视频| 久久精品国产一区二区电影| 欧美黑人性生活视频| 中文字幕国产亚洲| 亚洲国产精品久久| 亚洲色图第一页| 国产情人节一区| 欧美日韩精品国产| 国产婷婷成人久久av免费高清| 欧美精品一区在线播放| 亚洲精品美女久久久| 国产精品国产福利国产秒拍| 亚洲美女av在线播放| 国产欧美一区二区三区久久| 国产精品美女久久久久av超清| 日本不卡视频在线播放| 久久99久久99精品免观看粉嫩| 欧美疯狂xxxx大交乱88av| 亚洲影院色在线观看免费| 欧美理论在线观看| 亚洲激情电影中文字幕| 成人激情春色网| 91精品久久久久久久久久| 国产精品欧美日韩久久| 国产成人精品a视频一区www| 亚洲欧美制服第一页| 亚洲一区二区三区在线视频| 欧美在线免费观看| 久久艳片www.17c.com| 久久久久久18| 狠狠综合久久av一区二区小说| 久久久久久一区二区三区| 91久久国产精品| 97超级碰碰碰| 国产经典一区二区| 亚洲精品电影网在线观看| 91久久国产婷婷一区二区| 亚洲亚裔videos黑人hd| 久久噜噜噜精品国产亚洲综合| 69视频在线免费观看| 欧美在线一区二区三区四| 国产成人福利视频| 在线精品高清中文字幕| 这里只有精品在线播放| 中文字幕欧美日韩在线| 亚洲成av人片在线观看香蕉| 欧美性xxxx极品hd满灌| 欧美日本高清一区| 国产69久久精品成人看| 亚洲深夜福利视频| 亚洲综合中文字幕在线| 国产亚洲激情视频在线| 成人黄色免费网站在线观看| 欧美黑人巨大xxx极品| 91经典在线视频| 亚洲欧美制服丝袜| 中文字幕亚洲二区| 91色中文字幕| 亚洲区中文字幕| 久久久久久久久久久网站| 亚洲精品日韩欧美| 国产成人a亚洲精品| 日本电影亚洲天堂| 久久久久久久久国产| 欧美又大粗又爽又黄大片视频| 欧美人成在线视频| 国产精品久久久久久久久免费| 欧美激情a∨在线视频播放|