日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

异步编程异常和死锁处理

發(fā)布時間:2024/4/15 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 异步编程异常和死锁处理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

在.NET異步編程中,通常使用async和await這對黃金搭檔,返回類型使用Task或Task<T>。在方法前面加async表示這個方法運行異步,在方法內(nèi)使用await表示執(zhí)行一個異步等待。

?

下面是一個簡單例子:

?

static void Main(string[] args) { Doth(); Console.ReadKey(); } static async Task Doth() { int i = 2; await Task.Delay(TimeSpan.FromSeconds(2)); i += 2; await Task.Delay(TimeSpan.FromSeconds(2)); Console.WriteLine(i); }

?

當執(zhí)行DoSth方法,第一個await執(zhí)行一個異步等待,當執(zhí)行完成,就繼續(xù)執(zhí)行下面的代碼。在async修飾的方法內(nèi)部,一個await就是一個異步等待,可以包含多個await, 每一個await執(zhí)行完畢才會執(zhí)行它后面的代碼,也就是說在DoSth內(nèi)部是同步的。

?

各個await在哪個線程中運行呢?

?

默認情況下是在當前線程中運行,不過.NET提供了ConfigureAwait方法,用來設(shè)置await在哪個線程中運行。

?

static async Task Doth() { int i = 2; await Task.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false); i += 2; await Task.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false); Console.WriteLine(i); }

?

以上,當?shù)谝粋€await運行在控制臺項目所在的線程中,第二個await將在線程池上運行。

?

我們無法保證每個await不會拋出異常,通常按如下的方式捕獲異常。

?

async Task DosthAsync() { try { await PossibleExceptionAsync(); } catch(NotSuppotedException ex) { LogException(ex); throw; } }

?

由于拋出的異常會放在Task對象中,所以也可以這么寫:

?

async Task DosthAsync() { Task task = PossibleExceptionAsync(); try { await task; } cach(NotSupportedException ex) { LogException(ex); throw; } }

?

異步編程也會出現(xiàn)死鎖。

?

async Task DoSthSync() { await Task.Delay(TimeSpan.FromSeconds(1)); } void FirstThing() { Task tak = DoSthSync(); task.Wait(); }

?

以上,如果調(diào)用FirstThing方法就會出現(xiàn)死鎖的情況。

?

→執(zhí)行FirstThing方法
→在FirstThing方法內(nèi)部執(zhí)行DoSthSync方法,這時,當前上下文線程被阻塞
→來到DoSthSync方法中,其中的await試圖捕獲當前上下文線程,而當前的上下線程已經(jīng)被阻塞在那里了,造成死鎖。

?

死鎖如何解決死鎖呢?

?

可以在DoSthSync內(nèi)部不使用當前上下文線程,改用線程池中的線程,修改如下:

?

async Task DoSthSync() { await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false); }

?

或者,讓FirstThing變成一個異步方法。修改如下:

?

async Task DoSthSync() { await Task.Delay(TimeSpan.FromSeconds(1)); } async Task FirstThing() { await DoSthSync(); }

轉(zhuǎn)載于:https://www.cnblogs.com/darrenji/p/4710425.html

總結(jié)

以上是生活随笔為你收集整理的异步编程异常和死锁处理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。