2010-08-14 94 views
0

我想解決一個跨線程異常,無效對象異常。下面是詳細信息:我有兩個後臺工作線程(將有更多,但我還沒有編碼他們,我只是編碼引擎,他們都在這個時候運行。這是一個C#,Windows窗體app。每隔一段時間,BGW都會調用UpdateUI,它會對UI進行大量更新,相同的UpdateUI用於所有線程,因此它是鎖定的,性能下降非常小,無關緊要很顯然,我現在正在用一個BGW來改變用戶界面,也就是不同的線程,所以我會得到一個交叉線程異常,所以我需要Invoke()或BeginInvoke(),但是每當我這樣做時,都會以某種方式,所有這些耗時的過程都會合併到同一個線程中,並且按順序執行,而不是同時執行。這是因爲我的代碼是錯誤的,不是因爲其他原因,我真的不知道使用Invoke()和BeginInvoke(),所以這是從類似的線程複製代碼,而不是我自己的,但它仍然無法正常工作,只是看它,它看起來很奇怪,而不是我會做的。跨線程異常無效對象異常

所以,你能幫我糾正我的Invoke()代碼嗎?它刪除了異常,但將它們全部合併到一個線程中,但不完全確定哪一個是UI線程?另外,我的UpdateUI()很長很複雜,所以理想情況下,我會調用整個方法(基本上整個事情都需要調用),而不是單獨執行每一行,如果可能的話,就像調用代碼所做的那樣。我再說一遍,這不是我用來調用方法的方法,只是簡單地改變「Enabled」狀態,這就是爲什麼它看起來很奇怪。

非常感謝你提前!

理查德

MethodInvoker method = delegate 
{ 
    label3.Enabled = true; 
}; 

if (InvokeRequired) 
{ 
    BeginInvoke(method); 
} 
else 
{ 
    method.Invoke(); 
} 

回答

2

爲了確保您的UpdateUI方法是在GUI線程上執行,使用以下命令:

public void UpdateUI() { 
    if (this.InvokeRequired) { 
     this.Invoke(new MethodInvoker(UpdateUI)); 
    } else { 
     // Changes to UI are made here. 
    } 
} 

更換this與參考您的形式,如果合適的。

+0

這個工程!我不知道如何謝謝你!對不起,我不能對此投票!再次感謝! Richard – niemiro 2010-08-14 15:50:34

1

你調用調用或BeginInvoke應該是存在於目標線程控制。所以你應該使用Control.InvokeControl.BeginInvoke

內部調用實際上向UI線程消息隊列發送消息(同步),並且BeginInvoke將消息(異步)發送到消息隊列,因爲消息隊列一次處理一個消息,您可能不需要鎖定對Invoke/BeginInvoke的調用。

+0

這也有助於解決問題!非常感謝! – niemiro 2010-08-14 15:52:27