當前位置:
首頁 > 知識 > 多線程和非同步編程示例和實踐-踩過的坑

多線程和非同步編程示例和實踐-踩過的坑

上兩篇文章,主要介紹了Thread、ThreadPool和TPL

本文中,分享兩則我們在做多線程和非同步編程中實際踩過的坑,實際生產環境遇到的問題,以及解決辦法。

1. HttpClient

業務場景:使用HttpClient實現第三方業務推送,當第三方的Http伺服器不通、或者返回很慢時

  • 線程數暴漲
  • Asp.NetAsp.Net MVC場景下,並發多線程導致的線程阻塞:HttpClient.PostAysnc/GetAsync.Result

第一種線程數暴漲的問題,很容易理解,線程執行的慢,線程創建的速度快,一直在執行,導致線程不斷創建線程、線程數不斷暴漲。

根本原因是HttpClient的超時時間配置的太長,這點存於業務設計的問題,理論上簡單請求3s沒響應就該超時了,複雜長時間請求使用非同步任務(我們的消息應用中心)處理。

第二種,Asp.Net或者Asp.Net MVC場景下,使用HttpClient,同時GetAsync.Result,非同步變同步,這就會出現請求Hang住,線程死鎖、請求沒響應。

根本原因Http非同步請求的上下文的互相等待導致的。詳細分析可以參考下面的link:

有什麼好的解決方案嗎

  • HttpWebRequest代替HttpClient實現各類Http請求,這個類雖然是.net 2.0下的,但是功能的確很強大,應用一般的Http請求沒啥問題!
  • 使用HttpWebRequest實現同步Get、Post請求,避免在Asp.Net場景下使用HttpClient.PostAsync/GetAsync.Result(非同步變同步)帶來的線程死鎖,因為Asp.Net機制下Http非同步請求的上下文的互相等待導致的。
  • 合理設置Http請求的超時時間,超時即返回,防止線程數暴漲
  • 對於第三方伺服器的通信,建議在內存中維護一個聯通性狀態字典,每隔一段時間更新一次,如果不通,直接就不發起Http請求了,這個策略更像是設計上的優化,但是效果很好!

上兩個示例代碼:

多線程和非同步編程示例和實踐-踩過的坑

如果非用HttpClient不可,也是有招的:

多線程和非同步編程示例和實踐-踩過的坑

很簡單,從WebApi,或者Controller這一層全部非同步化。前後全部非同步。同時,

設置:ConfigureAwait(false)

2. Winform、Console或者Windows服務下,前台線程異常導致的進程退出

這個問題是很頭疼的,主要是在提供的服務容器運行的插件代碼中,使用了Thread,默認是前台線程,未正確處理異常,線程異常後,導致主進程退出!!!

業務場景:Windows 服務版本下的消息應用中心,個推使用New Thread推送消息,線程未處理異常,異常後導致Windows Service異常關閉!

結果很頭大,就是整個消息應用中心進程退出了,所有消息處理業務全部受影響!

根本原因:通過New Thread方式創建的線程,系統默認都是前台線程(IsBack),前台線程異常如果未處理,會導致應用程序退出,即使註冊了AppDomain.CurrentDomain.UnhandledException事件處理,應用程序依然會掛掉。

解決方案:在線程內部合理處理異常:記日誌、返回值處理,但是不能throw

補充:這裡引出了一個重要的知識點:前台線程和後台線程

兩者的區別就是:

  • 應用程序必須運行完所有的前台線程才可以退出;
  • 對於後台線程,應用程序則可以不考慮其是否已經運行完畢而直接退出,所有的後台線程在應用程序退出時都會自動結束。

那麼,Thread、線程池的線程、Task都各自屬於哪一類線程?

使用Thread建立的線程默認情況下是前台線程,即線程屬性IsBackground=false.

屬於託管線程池的線程(即其 IsThreadPoolThread 屬性為 true 的線程)是後台線程

Task都是後台線程:Task需要在其運行過程中至少有一個前台線程在跑,否則會直接退出.

周國慶

2017/6/16

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 達人科技 的精彩文章:

EF Core學習Code First
cordova 插件開發

TAG:達人科技 |

您可能感興趣

核桃編程:讓孩子學習編程的進步清晰可見
程序員的編程能力與編程年齡
編程測試,程序員過不去的坎?
編程進階之路:用簡單的面向對象編程提升深度學習原型
編程小白和Ta的進階之旅
發生在編程過程中的五件趣事
最硬核的遊戲,完整還原編程的步驟,不會編程連任務都看不懂
多地編程協作的必備技——遠程結對編程
AI時代學什麼穩賺不賠?編程,編程,編程
數控行業現狀與前景的探討,一個編程工程師的肺腑之言
傲夢編程推出「少兒編程萬人普及計劃」,演繹編程魅力
學習編程,真正的攔路虎是什麼?
小程序對實體店的好處,怎麼賺錢?介紹一個免編程小程序製作平台
一個女程序員的編程之路
異型螺紋編程實例,擴展你的思路
編程向未來,科技強國夢——雲和數據即將推出「少兒編程」課程!
從「少兒編程」到編程
編程前的準備
在真實工作中的編程是怎麼樣的,與學校里有什麼不同?
谷歌軟體工程師分享編程經驗:有效的流程很關鍵