摘自其他人部落格,自己試過確實解決問題。(如在自己定義的執行緒裡面給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 還有委託,...