3

我收到一个错误"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当它显然应该返回真时突然返回假?

4

2 回答 2

6

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

     Control.CheckForIllegalCrossThreadCalls = False
于 2013-12-31T21:20:00.587 回答
2

从 MSDN 文档 -

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

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

当 InvokeRequired 在后台线程上返回 false 时,您还可以通过检查 IsHandleCreated 的值来防止这种情况。如果尚未创建控制句柄,则必须等到它创建完成后,才能调用 Invoke 或 BeginInvoke。通常,仅当在应用程序的主窗体的构造函数中创建后台线程时(如在 Application.Run(new MainForm()) 中,在显示窗体或调用 Application.Run 之前)才会发生这种情况。

不相关的代码更改可能会延迟创建控制句柄。在检查需要调用之前,您可以通过显式创建句柄进行检查吗?

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

请参阅此处的答案。他们可能会引起你的兴趣。

于 2013-07-08T20:14:27.057 回答