如何從其創建的線程以外的線程訪問控件,避免跨線程錯誤?如何從不同的線程訪問控件?
下面是該我的示例代碼:
private void Form1_Load(object sender, EventArgs e)
{
Thread t = new Thread(foo);
t.Start();
}
private void foo()
{
this.Text = "Test";
}
如何從其創建的線程以外的線程訪問控件,避免跨線程錯誤?如何從不同的線程訪問控件?
下面是該我的示例代碼:
private void Form1_Load(object sender, EventArgs e)
{
Thread t = new Thread(foo);
t.Start();
}
private void foo()
{
this.Text = "Test";
}
有這個衆所周知的小圖案,它看起來像這樣:
public void SetText(string text)
{
if (this.InvokeRequired)
{
this.Invoke(new Action<string>(SetText), text);
}
else
{
this.Text = text;
}
}
而且也有快速骯髒的修復,我不要不建議使用其他方式來測試它。
Form.CheckForIllegalCrossThreadCalls = false;
正確的答案,除了模式是imho衆所周知的:) – 2011-03-09 09:00:22
讓我們交換這些詞然後,因爲我不是意味着它在未知的意義上,只是「小模式」的一部分。 – 2011-03-09 09:03:08
您應該檢查Invoke方法。
檢查 - How to: Make Thread-Safe Calls to Windows Forms Controls
private void foo()
{
if (this.InvokeRequired)
{
this.Invoke(() => this.Text = text);
}
else
{
this.Text = text;
}
}
你應該InvokeRequired方法檢查,看看是否是同一個線程,不同的線程上。
MSDN參考:http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invokerequired.aspx
你的方法可以重構這種方式
private void foo() {
if (this.InvokeRequired)
this.Invoke(new MethodInvoker(this.foo));
else
this.Text = "Test";
}
有很多關於這個堆棧溢出的問題。 – ChrisF 2011-03-09 08:58:49
如果你是Winforms的新手,我建議從WPF開始。許多人可能會不同意,但是Winforms已經死了。在WPF中,這個問題是通過對每個組件排隊操作來解決的。 – Gilad 2011-03-09 09:07:27
Dupe of http://stackoverflow.com/questions/142003/cross-thread-operation-not-valid-control-accessed-from-a-thread-other-than-the-t http://stackoverflow.com/問題/ 3650109/cross-thread-operation-not-valid-control-textbox1-accessible-any-help-pl http://stackoverflow.com/questions/1809864/how-to-access-a-form-control-from -system-timers-timer-cross-thread-problem – gideon 2011-03-09 14:40:23