<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當(dāng)前位置: 首頁 - 科技 - 知識(shí)百科 - 正文

        ASP.NET 謹(jǐn)用 async/await

        來源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 22:35:10
        文檔

        ASP.NET 謹(jǐn)用 async/await

        ASP.NET 謹(jǐn)用 async/await:C# 5.0 引入 async/await 關(guān)鍵字,旨在簡(jiǎn)化異步編程模型,拋去語法糖就是 Net4.0 的 Task + 狀態(tài)機(jī)。其實(shí)在處理異步編程使用 Task 還是挺簡(jiǎn)單的,不過既然推出了新的語法糖,難免會(huì)嘗試一下,然而在使用中卻沒想象中那么單純。以下針對(duì)ASP.NET 應(yīng)用程
        推薦度:
        導(dǎo)讀ASP.NET 謹(jǐn)用 async/await:C# 5.0 引入 async/await 關(guān)鍵字,旨在簡(jiǎn)化異步編程模型,拋去語法糖就是 Net4.0 的 Task + 狀態(tài)機(jī)。其實(shí)在處理異步編程使用 Task 還是挺簡(jiǎn)單的,不過既然推出了新的語法糖,難免會(huì)嘗試一下,然而在使用中卻沒想象中那么單純。以下針對(duì)ASP.NET 應(yīng)用程

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

        異常捕獲

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

        async void

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

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

        async Task 或 async Task

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

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

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

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

        同步上下文

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

        注意:控制臺(tái)程序和.Net Core程序 將不會(huì)遇到這個(gè)問題,它們不需要同步上下文。

        死鎖

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

        以上代碼很完美的實(shí)現(xiàn)了死鎖。 默認(rèn)情況下,當(dāng) Wait() 未完成的 Task 時(shí),會(huì)捕獲當(dāng)前線程上下文,在 Task 完成時(shí)使用該上下文恢復(fù)方法的執(zhí)行。 當(dāng) async 方法內(nèi)的 await 執(zhí)行完成時(shí),它會(huì)嘗試獲取調(diào)用者線程所在的上下文執(zhí)行方法的剩余部分, 但是該上下文已含有一個(gè)線程,該線程在等待 async 方法完成。然后它們相互等待對(duì)方,然后就沒有然后了,死在那里。

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

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

        當(dāng) await 等待完成時(shí),它會(huì)嘗試在線程池上下文中執(zhí)行 async 方法的剩余部分,因此就不存在死鎖。

        應(yīng)用程序崩潰

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

        如果調(diào)用一個(gè) async 方法。如果使用 await 等待,當(dāng)前線程立馬被釋放回線程池,線程的上下文信息會(huì)被保存。如果沒有使用 await(async void 的方法,必然沒有辦法使用 await),調(diào)用 async 方法之后,代碼會(huì)繼續(xù)往下執(zhí)行,執(zhí)行完成后當(dāng)前線程被釋放回線程池,線程的上下文信息不會(huì)被保存。當(dāng) async 中的異步任務(wù)執(zhí)行完成后,會(huì)從線程池中獲取一個(gè)線程繼續(xù)執(zhí)行剩余代碼,同時(shí)會(huì)獲取當(dāng)初調(diào)用者所在線程的上下文信息(如果當(dāng)初調(diào)用者所在線程沒有釋放回線程池,上下文信息可以獲取到)。那么問題就來了,如果當(dāng)初調(diào)用者沒有使用 await 并且 所在線程釋放回線程池了,上下文信息因?yàn)闆]有被保持下來,就獲取不到了,這時(shí)候會(huì)拋出異常 未將對(duì)象引用設(shè)置到對(duì)象的實(shí)例 ,經(jīng)過測(cè)試這個(gè)異常信息并不一定每次都會(huì)出現(xiàn),原因和線程的釋放有關(guān),調(diào)用者所在線程的上下文信息存在就不會(huì)拋出異常。異常錯(cuò)誤信息如下,這個(gè)異常最終會(huì)導(dǎo)致應(yīng)用程序集停止。

        在 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)
        --- 引發(fā)異常的上一位置中堆棧跟蹤的末尾 ---
         在 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()

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

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

        總結(jié)

        以上所述是小編給大家介紹的ASP.NET 謹(jǐn)用 async/await,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        ASP.NET 謹(jǐn)用 async/await

        ASP.NET 謹(jǐn)用 async/await:C# 5.0 引入 async/await 關(guān)鍵字,旨在簡(jiǎn)化異步編程模型,拋去語法糖就是 Net4.0 的 Task + 狀態(tài)機(jī)。其實(shí)在處理異步編程使用 Task 還是挺簡(jiǎn)單的,不過既然推出了新的語法糖,難免會(huì)嘗試一下,然而在使用中卻沒想象中那么單純。以下針對(duì)ASP.NET 應(yīng)用程
        推薦度:
        標(biāo)簽: 使用 net ASP.NET
        • 熱門焦點(diǎn)

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲精品无码少妇30P| 亚洲成年人免费网站| 亚洲一级特黄大片无码毛片 | 哒哒哒免费视频观看在线www | 久久99国产综合精品免费| AA免费观看的1000部电影| 亚洲 另类 无码 在线| 亚洲va无码va在线va天堂| 亚洲天堂2017无码中文| 国产精品99爱免费视频| av免费不卡国产观看| 亚洲欧洲一区二区三区| 亚洲色偷精品一区二区三区| 日韩精品免费在线视频| 情侣视频精品免费的国产| 久久精品亚洲一区二区| 色欲A∨无码蜜臀AV免费播| 国产亚洲AV夜间福利香蕉149| 亚洲一区二区三区写真| 国产免费一区二区三区VR| jlzzjlzz亚洲jzjzjz| 成人片黄网站色大片免费观看APP| 日韩免费三级电影| 污视频网站在线免费看| 18禁成年无码免费网站无遮挡| 亚洲AV无码专区电影在线观看 | 无码av免费一区二区三区| 亚洲国产成人精品无码区在线网站| 99麻豆久久久国产精品免费 | 亚洲国产精品综合久久久| 成年女人毛片免费播放视频m| 亚洲精品视频在线| 国产成人精品免费视频大全| 久久综合图区亚洲综合图区| 国产成人A在线观看视频免费| 精品在线观看免费| 看全色黄大色大片免费久久| 亚洲av日韩av无码av| 免费va在线观看| 91久久精品国产免费一区| 国产精品亚洲色婷婷99久久精品|