2013-11-24 15 views
2

看来,C#有时会为跨线程操作抛出异常。例如,您可以尝试在Windows窗体程序中运行此示例代码:当我允许跨线程访问和什么时候我不是?

public Form1() 
    { 
     InitializeComponent(); 
     Thread setTextT = new Thread(TextSetter); 
     setTextT.Start(); 
    } 

    private void TextSetter() 
    { 
     //Thread.Sleep(4000); 
     textBox1.Text = "Hello World"; 
    } 

它不会抛出任何异常,一切似乎都正常工作。现在,当您取消注释Thread.Sleep行时,它会为尝试的跨线程访问引发异常。

为什么会出现这种情况?

+0

有时,它不会对你吹起来。虽然你不应该这样做。 –

回答

5

这是因为跨线程检查只发生在the window's handle已创建后,因为您正在检查的是跨窗口句柄的线程访问。当你没有睡眠时,代码在第一次显示控件之前运行得足够快(首次显示控件时就会创建控件)。

的easyist办法知道,如果你需要小心的UI控件的跨线程访问时只检查InvokeRequired,如果这是真的,你需要调用Invoke(或BeginInvoke如果你不想等待它完成)来创建控件的线程。

+3

这就是为什么你应该在窗体的Load事件中启动线程,而不是从构造函数中启动线程。这样,你会得到更一致的行为。 – Baldrick

+0

@Baldrick好点。 @Andrew Load事件发生在表单加载和显示之后,这样你现在知道你不需要担心在你的方法中创建的控件。 –

0

试试这个:

public Form1() 
    { 
     InitializeComponent(); 
     Thread setTextT = new Thread(TextSetter); 
     setTextT.Start(); 
    } 

    private void TextSetter() 
    { 
     //Thread.Sleep(4000); 
     //textBox1.Text = "Hello World"; 
     //You have to Invoke your action to the UI thread 
     Invoke(new Action(()=>textBox1.Text = "Hello World")); 
    } 
相关问题