跨线程操作无效,控制从其创建的线程以外的线程访问

时间:2013-07-08 19:41:07

标签: c# multithreading

我收到错误"Cross-thread operation not valid: Control 'AllOtherStatus' accessed from a thread other than the thread it was created on."

我有以下代码:_output设置为AllOtherStatus,查看调试器,_output.InvokeRequiredfalse

此代码工作正常,直到我更改了一个不使用此代码的无关类。代码到达else语句然后抛出异常。

private void Thread(Object p)
        {
        lock (this)
            {
            if (_output.InvokeRequired)
                {
                if(s!= null)
                    _output.Invoke(new MethodInvoker(delegate { _output.AppendText(s); }));
                }
            else
                _output.AppendText(s);

            s = null;
            }
        }

所以我的问题是为什么_output.InvokeRequired突然返回时会突然返回false?

2 个答案:

答案 0 :(得分:6)

在表单加载或线程执行前的其他地方使用它

     Control.CheckForIllegalCrossThreadCalls = False

答案 1 :(得分:2)

来自MSDN文档 -

  

如果不需要Invoke,则InvokeRequired可以返回false(调用   发生在同一个线程上),或者如果控件是在a上创建的   不同的线程但尚未创建控件的句柄。

     

如果尚未创建控件的句柄,则为您   不应该简单地调用控件上的属性,方法或事件。   这可能会导致控件的句柄在后台创建   线程,在没有消息泵的情况下隔离线程上的控件   使应用程序不稳定。

     

您还可以通过检查值来防止这种情况   当InvokeRequired在后台返回false时,IsHandleCreated   线。如果尚未创建控制句柄,则必须等待   直到它在调用Invoke或BeginInvoke之前创建。   通常,只有在创建后台线程时才会发生这种情况   应用程序主要形式的构造函数(如   Application.Run(new MainForm()),在表单显示之前或   已经调用了Application.Run。

不相关的代码更改可能会延迟创建控件句柄。您可以在检查所需的调用之前通过显式创建句柄来检查 -

var handle = this.Handle;
if (_output.InvokeRequired)
{
  .....
}

参考答案here。他们可能是你的兴趣。