C 跨執行緒呼叫窗體控制項的問題

2021-06-19 18:29:40 字數 2027 閱讀 3022

前段時間遇到跨執行緒呼叫窗體控制項的問題,其實一句話system.windows.forms.control.checkforillegalcrossthreadcalls = false;就可以解決,但感覺會有不穩定因素,因此在網上找了一些相應的文章感覺還不錯,第一種用的比較順手:

(注:在devexpress控制項中用devexpress.data.currencydatacontroller.disablethreadingproblemsdetection = true;)

不過windows 窗體體系結構對執行緒使用制定了嚴格的規則。如果只是編寫單執行緒應用程式,則沒必要知道這些規則,這是因為單執行緒的**不可能違反這些規則。然而,一旦採用多執行緒,就需要理解windows 窗體中最重要的一條執行緒規則:除了極少數的例外情況,否則都不要在它的建立執行緒以外的執行緒中使用控制項的任何成員。本規則的例外情況有文件說明,但這樣的情況非常少。這適用於其類派生自system.windows.forms.control的任何物件,其中幾乎包括ui 中的所有元素。所有的ui元素(包括表單本身)都是從control類派生的物件。此外,這條規則的結果是乙個被包含的控制項(如,包含在乙個表單中的按鈕)必須與包含它控制項位處於同乙個執行緒中。也就是說,乙個視窗中的所有控制項屬於同乙個ui 執行緒。實際中,大部分windows窗體應用程式最終都只有乙個執行緒,所有ui活動都發生在這個執行緒上。這個執行緒通常稱為ui執行緒。這意味著您不能呼叫使用者介面中任意控制項上的任何方法,除非在該方法的文件說明中指出可以呼叫。該規則的例外情況(總有文件記錄)非常少而且它們之間關係也不大。請注意,以下**是非法的:

private thread mythread;

private void form1_load(object sender,eventargs e)

private void runsonworkerthread()

private void runsonworkerthread()

private void setcontrolsprop()

二、直接用system.eventhandle(可帶引數)

private thread mythread;

private void form1_load(object sender,eventargs e)

private void runsonworkerthread()

//直接用system.eventhandler,沒有必要自定義委託

private void updateui(object o, system.eventargs e)

private void runsonworkerthread()

}public void showprogress(string msg,int percentdone)

;begininvoke(new myprogresseventshandler(updateui), plist);

}private delegatevoid myprogresseventshandler(object sender,myprogressevents e);

private void updateui(object sender,myprogressevents e)

public class myprogressevents : eventargs

showprogress 方法對將呼叫引向正確執行緒的工作進行封裝。這意味著輔助線程**不再擔心需要過多關注ui細節,而只要定期呼叫showprogress 即可。

如果我提供乙個設計為可從任何執行緒呼叫的公共方法,則完全有可能某人會從ui執行緒呼叫這個方法。在這種情況下,沒必要呼叫begininvoke,因為我已經處於正確的執行緒中。呼叫invoke完全是浪費時間和資源,不如直接呼叫適當的方法。為了避免這種情況,control類將公開乙個稱為invokerequired的屬性。這是「只限ui 執行緒」規則的另乙個例外。它可從任何執行緒讀取,如果呼叫執行緒是ui執行緒,則返回假,其他執行緒則返回真。這意味著我可以按以下方式修改包裝:

public void showprogress(string msg,int percentdone)

else

C 跨執行緒呼叫窗體控制項

前段時間遇到跨執行緒呼叫窗體控制項的問題,其實一句話system.windows.forms.control.checkforillegalcrossthreadcalls false 就可以解決,但感覺會有不穩定因素,因此在網上找了一些相應的文章感覺還不錯,第一種用的比較順手 注 在devexpr...

如何跨執行緒呼叫winform窗體控制項

方法一 直接關閉異常,不檢查跨執行緒呼叫private void form1 load object sender,eventargs e 方法二 利用委託 舉例1 delegate void tasktype string sztext 這裡是因為執行緒的方法只能是object型別 void th...

C 跨執行緒呼叫控制項

在c 應用程式開發中,我們經常需要把ui執行緒和工作執行緒分開程式設計,為了防止介面停止響應。同時,我們也需要在工作執行緒中去更新ui介面的控制項,在clr的執行緒安全中並不允許我們直接在工作執行緒操作ui介面。因此,介紹以下三種方式進行跨執行緒操作ui。private void button2 c...