跨线程操作无效,从创建控件的线程以外的线程访问控件
本文关键字:线程 控件 访问 操作 无效 创建 | 更新日期: 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.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
在本应返回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)
{
.....
}
请参阅此处的答案。它们可能会引起你的兴趣。