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)
,是否仍然会出错?是的,我仍然会遇到相同的错误我将文本框设置为在创建后立即显示文本,这解决了问题。