在搜索完成之前关闭我的应用程序时出现System.InvalidOperationException错误。当我关闭Form1_FormClosing时,我告诉我所有的线程都要中止。在一个线程中,它具有finalize,它调用委托函数,该函数告诉表单中的一个控件更改其文本。当发生这种情况时,我得到上面的例外以及“附加信息:在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke。”
我该怎么做才能纠正这个问题?我可以添加一个isClosing标志并在更新文本之前检查它,但这感觉就像一个黑客并掩盖了问题。我该如何正确解决这个问题?
答案 0 :(得分:1)
这种情况正在发生,因为托管控件正在处理并且不再有其处理,但您还没有关闭窗口,所以您仍然可以看到它。
您可以创建一个包含Invoke
调用的函数,并在调用IsHandleCreated
之前检查Invoke
。如果IsHandleCreated
为false,则无法拨打Invoke
,您可以忽略该来电。
public static class ControlExtensions
{
public static TResult InvokeEx<TControl, TResult>(this TControl control,
Func<TControl, TResult> func)
where TControl : Control
{
if (!control.IsHandleCreated)
return default(T);
if (control.InvokeRequired)
return (TResult)control.Invoke(func, control);
else
return func(control);
}
public static void InvokeEx<TControl>(this TControl control,
Action<TControl> action)
where TControl : Control
{
control.InvokeEx(c => { action(c); return c; });
}
}
所以现在只需用Invoke
从你的线程中包装任何InvokeEx
,它将处理控件何时被处理并且不再有句柄。
this.InvokeEx(c => c.label1.Text = "Hello world");
答案 1 :(得分:1)
我同意Samuel,但也会检查IsDisposed
:
void Handler()
{
if (ctrl.IsDisposed || !ctrl.IsHandleCreated) return;
if (ctrl.InvokeRequired)
Invoke(...);
else {
...
}
}