C 執行非同步操作的幾種方式比較和總結

2021-08-07 18:49:17 字數 2263 閱讀 1298

之前寫程式的時候在遇到一些比較花時間的操作例如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(預設)。

C 執行非同步操作的幾種方式

執行緒非同步按鈕 private void threadbutton click object sender,routedeventargs e start 執行緒池非同步按鈕 private void threadpoolbutton click object sender,routedevent...

IOS延時執行的幾種方式比較

四種延時執行某函式的方法及其一些區別。假如延時1秒時間執行下面的方法。void delaymethod self performselector selector delaymethod withobject nil afterdelay 1.0f 此方式要求必須在主線程中執行,否則無效。是一種非阻...

非同步請求的幾種方式

1.最原始的js new xmlhttprequest 由於瀏覽器相容的原因,複雜,多使用基於jquery的非同步請求方法 內部封裝 2.基於jquery的ajax方法 1 load url,data callback 例項如下 test load test.php function 2 getjs...