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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

一次Task.Run异常问题的排查

發布時間:2023/12/4 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一次Task.Run异常问题的排查 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

????????最近在測試一個功能代碼時發現一個非常奇怪的問題,主要是Task.Run引起一些不符合邏輯的錯誤,以下針對這一問題排查的總結。

問題代碼

????????可以建個控制臺程序來運行以下代碼

class Program{static User user = new User();static void Main(string[] args){for (int i = 0; i < 50; i++){Task.Run(user.Init);}System.Threading.Thread.Sleep(-1);}}public class User{private bool mInit = false;private Task OnInit(){Console.WriteLine("User init");System.Threading.Thread.Sleep(1000);return Task.CompletedTask;}public void Init(){lock (typeof(User)){if (!mInit){var task = Task.Run(this.OnInit);if (!task.Wait(5000)){throw new TimeoutException("user init error!");}mInit = true;}}}}

以上代碼執行的結果非常奇怪,當在Debug模式下運行,會拋出超時錯誤。

運行在release模式下則會引起OnIint方法被執行多次,lock完全起不了作用。。

和朋友討論過程中說lock不要和Task.Run混用,但Task.Wait的實現是基于線程信號量的和async/await是有著本質的差異。抱著解決問題的思路把Task.Run直接改成了線程池方式運行,但結果還是一樣。由于找不到問題原因最終去dotnet上提個issues,看一下能提供什么意見。

問題的發現

????????對于一個程序員來說問題沒解決怎能安心呢,隔一天issues沒有響應于是開啟的解決問題的碰撞模式。在throw timeout里打個斷點看一下情況,結果無意中發現Task的狀態是WaitingForActivation

狀態描述是等待內部調度激活,意思是說這代碼并不是不執行或執行有問題,而因為某些狀態導致Task還在等待執行中。然后針對這一問題在網查找了一下才發現這問題的原因,主要問題是for 50已經把線和池中的線程抽光了,然然后在Init方法使用Task.Run的時候就只能等待。。。加上方法后面Task.Wait導致當前線程無法回歸到池,所以就只能引起超時間異常!如果這里的Task.Wait不加上個超時,那這測試代碼就直接處于假死狀態無法繼續工作,一個等待一個試圖獲取線程操作從而形成一個類似于死鎖的問題!

總結

????????當你在使用Task.Run時出現一些非常意想不到的結果時可以通過Task.Status狀態可以更好的定位到問題。Task默認也是基于線程池的,所以在使用Task.Run和Task.Wait的就要注意這一點,雖然可以通過加大線程池的最小數量來解決低并發問題,但高并發下還是會存在線程資源不足的情況;為了確保不出現類似于死鎖的問題,請在使用Task.Wait必須加上超時時間,并且是越短越好,畢竟Wait方法是基于線程阻塞。

BeetleX

開源跨平臺通訊框架(支持TLS)
輕松實現高性能:tcp、http、websocket、redis、rpc和網關等服務應用

https://beetlex.io

如果你想了解某方面的知識或文章可以把想法發送到

henryfan@msn.com|admin@beetlex.io

總結

以上是生活随笔為你收集整理的一次Task.Run异常问题的排查的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。