我有一个winforms应用程序,问题与线程有关.因为我调用'MyCustomCode()来创建一个新线程,并调用方法'SomeMethod()'然后访问MessageBox.Show(...).
问题与线程有关,因为新创建的线程正在尝试访问在另一个线程上创建的控件.
我收到错误:
跨线程操作无效:控制'TestForm'从其创建的线程以外的线程访问.
public TestForm()
{
    InitializeComponent();
    // custom code
    //
    MyCustomCode();
}
public void SomeMethod()
{
    // ***** This causes an error  ****
    MessageBox.Show(this,   
        ex.Message, 
        "Error", 
        MessageBoxButtons.OK, 
        MessageBoxIcon.Error
    );
}
private void InitializeAutoUpdater()
{
        // Seperate thread is spun to keep polling for updates
        ThreadStart ts = new ThreadStart(SomeMethod);
        pollThread = new Thread(ts);
        pollThread.Start();
}
更新
如果你看一下这个例子http://www.codeproject.com/KB/cs/vanillaupdaterblock.aspx,CheckAndUpdate方法正在调用MessageBox.Show(..),这就是我的问题所在.我本以为代码很好用!
有趣的是,这个代码在星期五工作得很好???
您无法从多个线程访问UI元素.
解决此问题的一种方法是使用UI元素(如消息框)调用具有委托的控件的Invoke方法.有些喜欢:
public delegate void InvokeDelegate();
public void SomeMethod()
{
    button1.Invoke((InvokeDelegate)doUIStuff);
}
void doUIStuff()
{
           MessageBox.Show(this,   
                ex.Message, 
                "Error", 
                MessageBoxButtons.OK, 
                MessageBoxIcon.Error
            );
}
为了避免跨线程异常(InvalidOperationException),这里是代码模式:
protected delegate void someGuiFunctionDelegate(int iParam);
protected void someGuiFunction(int iParam)
{
    if (this.InvokeRequired)
    {
        someGuiFunctionDelegate dlg = new 
            someGuiFunctionDelegate(this.someGuiFunction);
        this.Invoke(dlg, new object[] { iParam });
        return;
    }
    //do something with the GUI control here
}
我同意这很烦人,但它是Windows GUI控件不是线程安全的事实.可以通过某处或其他地方的标志关闭该异常,但不要这样做,因为它可能导致极难找到错误.