使用Task非同步執行方法 多執行緒 應用程式池

2021-09-27 13:47:07 字數 1808 閱讀 8905

備註:該方法是從應用程式程式所在的執行緒池中獲取執行緒,第一次建立非同步執行緒可能會費用一些時間,建立後不會立即銷毀,以便其他執行緒多次重複使用,對程式效能影響不大:

//

非同步執行修改使用者登入時間並傳送佇列--20171209-lixh

task.run(() =>);

之前寫程式的時候在遇到一些比較花時間的操作例如http請求時,總是會new乙個thread處理。對***xxasync()之類的方法也沒去了解過,倒也沒遇到什麼大問題。最近因為需求要求用devexpress寫介面,跑起來後發現比native控制項效率差好多。這才想到之前看到的「金科玉律」:不要在ui執行緒上執行介面無關的操作,因此集中看了下c#的非同步操作,分享一下自己的比較和總結。

ide:vs2015 community

.net版本:4.5

使用函式隨機休眠100到500毫秒來模擬耗時任務,並返回任務花費的時間,在ui執行緒上呼叫這個方法會造成阻塞,導致ui假死,因此需要通過非同步方式執行這個任務,並在資訊輸出區域顯示花費的時間。

主介面中通過各種不同按鈕測試不同型別的非同步操作

使用threadpool進行非同步操作的方法如下所示,需要注意的就是isbackground預設為false,也就是該執行緒對呼叫它的執行緒不產生依賴,當呼叫執行緒退出時該執行緒也不會結束。因此需要將isbackground設定為true以指明該執行緒是後台執行緒,這樣當主線程退出時該執行緒也會結束。另外跨執行緒操作ui還是要借助dispatcher.begininvoke(),如果需要阻塞ui執行緒可以使用dispatcher.invoke()。

task進行非同步操作時也是從執行緒池中獲取執行緒進行操作,不過支援的操作更加豐富一些。而且task可以支援返回值,通過task的continuewith()可以在task執行結束後將返回值傳入以進行操作,但在continuewith中跨執行緒操作ui仍需借助dispatcher。另外task也可以直接使用靜態方法task.run()執行非同步操作。

這個是c#5中的新特性,當遇到await時,會從執行緒池中取出乙個執行緒非同步執行await等待的操作,然後方法立即返回。等非同步操作結束後回到await所在的地方接著往後執行。await需要等待async task型別的函式。詳細的使用方法可參考相關資料,測試**如下所示。非同步結束後的會返回到呼叫執行緒,所以修改ui不需要dispatcher。

也可以把testtask包裝成async方法,這樣就可以使用上圖中注釋掉的兩行**進行處理。包裝後的非同步方法如下所示:

以上嘗試的方法除了直接使用thread之外,其他幾種都是直接或間接使用執行緒池來獲取執行緒的。從理論上來分析,建立執行緒時要給執行緒分配棧空間,執行緒銷毀時需要**記憶體,建立執行緒也會增加cpu的工作。因此可以連續建立執行緒並記錄消耗的時間來測試效能。測試**如下所示:

測試結果:

使用基於執行緒池的方法建立執行緒時,有時第一次會稍慢一些,應該是執行緒池內執行緒不足,時間開銷在0-15毫秒,第一次建立記憶體也會上公升。後面再測試時時間開銷為0毫秒,記憶體表現也很平穩,cpu開銷分布比較平均。測試結果如圖所示:

在執行非同步操作時應使用基於執行緒池的操作,從**的簡潔程度和可讀性上優先使用async/await方式。對於較老的.net版本可以使用task或threadpool。符合以下情況的可以使用thread:

1、執行緒建立後需要持續工作到主線程退出的。這種情況下就算使用執行緒池執行緒也不會歸還,實現不了復用,可以使用thread。

2、執行緒在主線程退出後仍需要執行的,這種情況使用執行緒池執行緒無法滿足需求,需要使用thread並制定isbackground為false(預設)。

測試程式**在:

更多專業前端知識,請上

【猿2048】www.mk2048.com

多執行緒非同步程式設計示例和實踐 Task

上篇博文中,我們介紹了thread和threadpool 多執行緒非同步程式設計示例和實踐 thread和threadpool 本文中我們繼續,說一下tpl task parallel library,簡稱tpl 在實際的開發中,使用執行緒池相當複雜,執行緒的異常捕獲 傳遞以及編排這些問題實現起來都...

非同步的使用 Task

新增task 引用命名空間 using system.threading.tasks console.writeline 主線程 task task new task task.start 啟動非同步 console.writeline load 執行上面 可以看到非同步是 最後才會執行 如果想放在...

Task 常用的多執行緒 基於多執行緒執行緒

thread 內容多,不易控制。task 好用 必須掌握 1 region private method 2 3 乙個比較耗時耗資源的私有方法 4 5 6private void dosomethinglong string name 7 9long lresult 0 10 for int i 0...