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

C# 跨线程操作无效,从创建控件的线程以外的线程访问控件,c#,multithreading,C#,Multithreading,我收到一个错误“跨线程操作无效:控件'AllOtherStatus'是从创建它的线程以外的线程访问的。” 我有以下代码:\u output设置为AllOtherStatus,查看调试器,\u output.invokererequired为false 这段代码运行良好,直到我更改了一个不使用这段代码的无关类。代码到达else语句,然后抛出异常 private void Thread(Object p) { lock (this) {

我收到一个错误
“跨线程操作无效:控件'AllOtherStatus'是从创建它的线程以外的线程访问的。”

我有以下代码:
\u output
设置为
AllOtherStatus
,查看调试器,
\u output.invokererequired
false

这段代码运行良好,直到我更改了一个不使用这段代码的无关类。代码到达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;
            }
        }

所以我的问题是为什么
\u output.invokererequired
突然返回false,而它显然应该返回true?

来自MSDN文档-

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

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

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

不相关的代码更改可能会推迟控件句柄的创建。在检查invoke required之前,是否可以通过显式创建句柄进行检查-

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

参考答案。它们可能是您感兴趣的。

在执行线程之前,在表单加载或其他地方使用此选项

     Control.CheckForIllegalCrossThreadCalls = False

什么类型的控件是AllOtherStatus,它是在哪里创建的?它是一个
文本框
,它是用windows窗体在
InitializeComponent()中创建的
MainForm下的第一行代码No,至少我不这么认为。它是在windows窗体中使用设计器创建的。如果注释掉
lock(this)
,是否仍然会出错?是的,我仍然会遇到相同的错误我将文本框设置为在创建后立即显示文本,这解决了问题。