C 跨執行緒呼叫

2022-02-07 22:15:12 字數 2553 閱讀 8465

private

thread mythread;

private

void

form1_load(

object

sender, eventargs e)

private

void

runsonworkerthread()

如果您在 .net framework

1.0版本中嘗試執行這段**,也許會僥倖執行成功,或者初看起來是如此。這就是多執行緒錯誤中的主要問題,即它們並不會立即顯現出來。甚至當出現了一些錯誤時,在第一次演示程式之前一切看起來也都很正常。但不要搞錯 — 我剛才顯示的這段**明顯違反了規則,並且可以預見,任何抱希望於「試執行時良好,應該就沒有問題」的人在即將到來的除錯期是會付出沉重代價的。

下面我們來看看有哪些方法可以解決這一問題。

一、system.windows.forms.methodinvoker 型別是乙個系統定義的委託,用於呼叫不帶引數的方法。

private

thread mythread;

private

void

form1_load(

object

sender, eventargs e)

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)

三、包裝 control.invoke 

雖然第二個方法中的**解決了這個問題,但它相當繁瑣。如果輔助線程希望在結束時提供更多的反饋資訊,而不是簡單地給出「finished!」訊息,則 begininvoke 過於複雜的使用方法會令人生畏。為了傳達其他訊息,例如「正在處理」、「一切順利」等等,需要設法向 updateui 函式傳遞乙個引數。可能還需要新增乙個進度欄以提高反饋能力。這麼多次呼叫 begininvoke 可能導致輔助線程受該**支配。這樣不僅會造成不便,而且考慮到輔助線程與 ui 的協調性,這樣設計也不好。對這些進行分析之後,我們認為包裝函式可以解決這兩個問題。

private

thread mythread;

private

void

form1_load(

object

sender, eventargs e)

private

void

runsonworkerthread()

}public

void

showprogress(

string

msg,

intpercentdone)

;begininvoke(

newmyprogresseventshandler(updateui), plist);

}private

delegate

void

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,

intpercentdone)

else

}

C 跨執行緒呼叫

問題 執行一下 報錯 大概意思就是跨執行緒操作,label沒法兒賦值 1.private void mainloop 8.解決方案 一 在5 6行中間新增以下 checkforillegalcrossthreadcalls false 禁止編譯器對跨執行緒訪問做檢查 二 使用deletgate in...

C 跨執行緒呼叫UpdateData

用sendmessage的方式解決 菜鳥步驟 1 在主窗體標頭檔案中用下列函式註冊windows訊息 const uintwm myupdatedata registerwindowmessage t myupdatedata 2 在主窗體標頭檔案中的訊息對映函式申明處新增下列對映 afx msg ...

C 跨執行緒呼叫控制項

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