我收到错误"Cross-thread operation not valid: Control 'AllOtherStatus' accessed from a thread other than the thread it was created on."
我有以下代码:_output
设置为AllOtherStatus
,查看调试器,_output.InvokeRequired
为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;
}
}
所以我的问题是为什么_output.InvokeRequired
突然返回时会突然返回false?
答案 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。他们可能是你的兴趣。