C 子執行緒呼叫主線程窗體的解決方法

2022-07-10 00:57:11 字數 1982 閱讀 3797

摘自其他人部落格,自己試過確實解決問題。(如在自己定義的執行緒裡面給textbox賦值)

由於windows窗體控制項本質上不是執行緒安全的。因此如果有兩個或多個執行緒適度操作某一控制項的狀態(set value),則可能會迫使該控制項進入一種不一致的狀態。還可能出現其他與執行緒相關的bug,包括爭用和死鎖的情況。所以vs2005這一改動便可以增強執行緒安全性。

我想大家更關心的是如何解決這個問題,如何才能操作其它執行緒中的控制項而不引發異常,接下來我們就來**下這個問題:

第一種方法:

這種方法我沒用過,因為大家推薦不要使用,所以我沒去實驗過,具體方法如下(摘自網上):

設定system.windows.forms.control.checkforillegalcrossthreadcalls=false;(winform.下)如果在你的程式初始化的時候設定了這個屬性,而且在你的控制項中使用的都是微軟framework類庫中的控制項的話,系統就不會再丟擲你上面所說的這個錯誤了。當然這只是為了將vs2003的**轉換到vs2005下所使用的一種常見的方法。不建議採用;

第二種方法,也是我今天主要要講的就是利用delegate和invoke這個方法:

思路:把想對另一線程中的控制項實施的操作放到乙個函式中,然後使用delegate**那個函式,並且在那個函式中加入乙個判斷,用 invokerequired來判斷呼叫這個函式的執行緒是否和控制項執行緒在同一執行緒中,如果是則直接執行對控制項的操作,否則利用控制項的invoke或 begininvoke方法來執行這個**。

在繼續講解下去之前我們先來看一下這裡提到的幾個方法(如果對以下兩個東東已經了解了就可以跳過)

首先是invoke

invoke的中文解釋是喚醒,它有兩種引數型別我們這裡只講一種即(delegate, object)

delegate就是前面提到的那個**,而object則是用來存放delegate所**函式的引數

msdn上關於invoke方法有如下說明:在擁有控制項的基礎視窗控制代碼的執行緒上,用指定的引數列表執行指定委託。

用通俗的話講就是利用控制項的invoke方法,使該控制項所在的執行緒執行這個**,也就是執行我們想對控制項進行的操作,相當於喚醒了這個操作;

其次是控制項的invokerequired這個屬性(個人翻譯為』喚醒請求』):

msdn上關於它的解釋是獲取乙個值,該值指示呼叫方在對控制項進行方法呼叫時是否必須呼叫invoke方法,因為呼叫方位於建立控制項所在的執行緒以外的執行緒中。

有通俗的話講就是返回乙個值,如果與控制項屬於同乙個執行緒,則不需要進行喚醒的請求,也就是返回值為false,否則則需要進行喚醒的請求,返回為 true

總感覺msdn上的翻譯讓人無法一看就明白,可能是自己智力不夠吧~~

最後就是我們的具體程式了:

delegate void aa(strings);//建立乙個**

private voidpri(string t)//這個就是我們的函式,我們把要對控制項進行的操作放在這裡

if(!richtextbox1.invokerequired)//判斷是否需要進行喚醒的請求,如果控制項與主線程在乙個執行緒內,可以寫成 if(!invokerequired)

messagebox.show("同一執行緒內");

richtextbox1.text =t;

else

messagebox.show("不是同乙個執行緒");

aa a1 =new aa(pri);

invoke(a1,new object );//執行喚醒操作

private voidform1_load(object sender, system.eventargse)

threadnewthread = new thread(new threadstart(ttread));

newthread.start();

voidttread()

pri("sdfs");

執行結果先調出乙個提示框顯示「不是同乙個執行緒」,然後跳出提示框顯示「同一執行緒內」,然後richtextbox1中的text值為sdfs;這樣便完成了對其它執行緒中的控制項進行操作

C 子執行緒呼叫主線程窗體的解決方法

由於windows窗體控制項本質上不是執行緒安全的。因此如果有兩個或多個執行緒適度操作某一控制項的狀態 set value 則可能會迫使該控制項進入一種不一致的狀態。還可能出現其他與執行緒相關的bug,包括爭用和死鎖的情況。所以vs2005這一改動便可以增強執行緒安全性。我想大家更關心的是如何解決這...

C 子執行緒呼叫主線程窗體的解決方法

摘自其他人部落格,自己試過確實解決問題。如在自己定義的執行緒裡面給textbox賦值 由於windows窗體控制項本質上不是執行緒安全的。因此如果有兩個或多個執行緒適度操作某一控制項的狀態 set value 則可能會迫使該控制項進入一種不一致的狀態。還可能出現其他與執行緒相關的bug,包括爭用和死...

C 執行緒呼叫主線程中的控制項

由於專案的需要,最近幾天一直在做串列埠和資料庫。由於c 使用的時間不長,所以在編寫 和除錯的過程中總是遇到意想不到的問題,比如在使用串列埠接收資料的時候,在接收資料事件中想把接收的資料放入乙個textbox作顯示,但是明明非常簡單的 在編譯的時候總是提示有錯誤。後來檢視網上資料,才知道c 還有委託,...