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

本文关键字:线程 控件 访问 操作 无效 创建 | 更新日期: 2023-09-27 18:21:37

我收到一个错误"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在本应返回true的情况下突然返回false?

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

在表单加载或线程执行之前的其他位置使用此选项

     Control.CheckForIllegalCrossThreadCalls = False

来自MSDN文档-

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

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

您还可以通过检查当InvokeRequired在后台返回false时,IsHandleCreated线如果尚未创建控件句柄,则必须等待直到在调用Invoke或BeginInvoke之前创建它。通常,只有在应用程序主窗体的构造函数(如Application.Run(new MainForm()),在表单显示之前或Application.Run已被调用。

不相关的代码更改可能会推迟控件句柄的创建。在检查所需调用之前,你能通过显式创建句柄进行检查吗?-

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

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