2011-07-04 73 views
2

我很新的C#所以原諒我,如果這是一個有點愚蠢的問題。 無論如何,我正在寫一個迄今爲止似乎進展順利的小聊天應用程序,我遇到了一個我似乎已經修復的問題,但我希望弄清楚爲什麼我需要這樣做。設置文本框線程問題

當我收到一個消息,我想更新一個文本框,所以我使用:

txtConnectedID.Text = "test"; 

但我收到此錯誤:

System.InvalidOperationException was unhandled by user code 
    Message=Cross-thread operation not valid: Control 'txtConnectedID' accessed from a thread other than the thread it was created on. 

現在,我覺得這事做停止運行兩次該方法而不正確更新?我不是100%的。所以,現在我有一個接受字符串的方法的一個代表,我呼籲:

private delegate void stringDelegate(string s); 

BeginInvoke(new stringDelegate(writeToIPBox), new object[] { e.ConnectedIP.ToString() }); 

private void writeToIPBox(string newIP) 
     { 
      txtConnectedID.Text = newIP; 
     } 

我不知道爲什麼我這樣做,它是如何的有什麼不同。如果不知道原因,我並不樂意這樣做。

在此先感謝

+0

http://stackoverflow.com/questions/1523878/cross-thread-operation-not-valid-in-c –

回答

1

您應該只嘗試從創建它們的線程更新控件。有很好的理由,因爲很容易出現競爭狀況。這些控件不是線程安全的,這是運行時幫助你一點。

取而代之,正如你所想的那樣,你需要在UI線程上更新它,這就是BeginInvoke正在做的事情;在UI線程上異步調用委託。

0

所有控制由UI線程(其中只有一個)所擁有,並試圖從這個異常另一個線程結果訪問它們。

BeginInvoke在UI線程上調用指定的委託,這就是它工作的原因。您還可以通過檢查txtConnectedID.InvokeRequired來檢查您是否在UI線程中。

0

花了決心的谷歌搜索的新分鐘,但我終於找到一個「權威的」參考:

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invokerequired%28v=vs.90%29.aspx

簡短的回答(從該頁面引用)是:控件在Windows窗體的綁定到特定的線程並且不是線程安全的。

本文還介紹瞭如何在內部處理這個問題......如果control.InvokeRequired(即我們已經從另一個線程調用)在內部處理調用......而不是在代碼中傳播代表。

就我個人而言,我從來沒有真正質疑爲什麼需要委託,我只是做了。好問題。

乾杯。基思。

0
private static void SetText(TextBox tb, string text) 
{ 
    if (tb.InvokeRequired) 
    { 
     var stDelegate = new StDelegate(SetText); 
     tb.Invoke(stDelegate, new object[] { tb, text }); 
    } 
    else 
    { 
     tb.Text = text; 
    } 
}