C 多執行緒與UI響應

2021-06-01 06:47:49 字數 2535 閱讀 5891

一.            概述

在使用c#進行應用程式設計時,經常會採用多執行緒的方式進行一些後台任務的工作。對於不同的應用場景,使用的策略也不盡相同。

1.      後台迴圈任務,少量ui更新:例如批量上傳檔案,並提供進度。這種情況使用backgroundworker元件是非常好的選擇。

2.      耗時的後台任務:這裡的耗時任務是指乙個時間較長的任務,並且不能精確獲取進度,如:呼叫乙個遠端webservice介面。這種情況可以開兩個執行緒,乙個工作,乙個更新ui(不能提供進度,只能顯示動畫表示系統在執行中)。

3.      耗時的ui任務:當工作壓力集中在ui響應上時,可以在工作者執行緒中增加延時,從而讓ui執行緒獲得響應時間。整個工作的總體時間會增加,但使用者響應效果會好很多。

二.            後台的迴圈任務,少量ui更新

這種情況使用backgroundworker元件是最好的選擇。(詳見附一)

三.            後台耗時任務

在後台執行乙個不可分解的耗時任務,需要進行介面更新,以便讓客戶看上去程式有所響應。這種情況下,ui執行緒一般也不知道工作執行緒何時結束,所以一般執行迴圈任務,當工作執行緒結束後,關閉ui執行緒就可以了。

thread uithread = null;

private void btnstart_click(object sender, eventargs e)

private void dosomething()

private void updateprogressthread()

}private void updateprogress(int v)

private void dosomething()

}private void loadpicture(int i)

", i);

listviewitem lvi = new listviewitem(text, 0);

this.listview1.items.add(lvi);

thread.sleep(200);//模擬耗時ui任務,非迴圈,不可分解

五.            補充

1.        invoke 和 begininvoke

在多執行緒程式設計中,我們經常要在工作執行緒中去更新介面顯示,而在多執行緒中直接呼叫介面控制項的方法是錯誤的做法,正確的做法是將工作執行緒中涉及更新介面的**封裝為乙個方法,通過 invoke 或者 begininvoke 去呼叫,兩者的區別就是乙個導致工作執行緒等待,而另外乙個則不會。

而所謂的「一面響應操作,一面新增節點」永遠只能是相對的,使 ui 執行緒的負擔不至於太大而以,因為介面的正確更新始終要通過 ui 執行緒去做,我們要做的事情是在工作執行緒中包攬大部分的運算,而將對純粹的介面更新放到 ui 執行緒中去做,這樣也就達到了減輕 ui 執行緒負擔的目的了。

private void button2_click(object sender, eventargs e)

", i);

listviewitem lvi = new listviewitem(text, 0);

this.listview1.items.add(lvi);

thread.sleep(200);

for (int j = 0; j < 10; j++)

}           

3.        lock

lock(object)

等價與try

finally

//通知執行緒停止

private void btnstop_click(object sender, eventargs e)

//工作者執行緒

private void backgroundworker_dowork(object sender, doworkeventargs e)

system.threading.thread.sleep(50);          //幹點實際的事

backgroundworker.reportprogress(i);         //報告進度}}

//執行緒進度報告

private void backgroundworker_progresschanged(object sender, progresschangedeventargs e)

//執行緒結束報告

private void backgroundworker_runworkercompleted(object sender, runworkercompletedeventargs e)

{           

this.btnstart.enabled = true;

this.btnstop.enabled = false;

總結:1、介面卡死主要原因是介面更新太頻繁,速度太快。

2、如果需要重複使用執行緒可以考慮使用執行緒池:threadqueue,

執行緒池特點:

thread池是一種方便管理的集合,而且你還可以設定最小執行緒數目,實現預生成很多執行緒

重點在於,你自己建立的執行緒被使用完後,總是被銷毀掉,而執行緒池中的執行緒在空閒的時候,還有一段生存週期

C 多執行緒與UI響應

一 概述 在使用c 進行應用程式設計時,經常會採用多執行緒的方式進行一些後台任務的工作。對於不同的應用場景,使用的策略也不盡相同。1.後台迴圈任務,少量ui更新 例如批量上傳檔案,並提供進度。這種情況使用backgroundworker元件是非常好的選擇。2.耗時的後台任務 這裡的耗時任務是指乙個時...

C 多執行緒與UI響應

一 概述 在使用c 進行應用程式設計時,經常會採用多執行緒的方式進行一些後台任務的工作。對於不同的應用場景,使用的策略也不盡相同。1.後台迴圈任務,少量ui更新 例如批量上傳檔案,並提供進度。這種情況使用backgroundworker元件是非常好的選擇。2.耗時的後台任務 這裡的耗時任務是指乙個時...

C 多執行緒與UI響應

一 概述 在使用c 進行應用程式設計時,經常會採用多執行緒的方式進行一些後台任務的工作。對於不同的應用場景,使用的策略也不盡相同。1.後台迴圈任務,少量ui更新 例如批量上傳檔案,並提供進度。這種情況使用backgroundworker元件是非常好的選擇。2.耗時的後台任務 這裡的耗時任務是指乙個時...