从Invoke
内部关闭表单,如下所示:
Invoke(new Action(() => {
Close();
MessageBox.Show("closed in invoke from another thread");
new Form1();
}));
表单关闭后,会抛出异常:
在窗口之前无法在控件上调用Invoke或BeginInvoke 句柄已经创建。
但仅限于.NET 4.0。在.NET 4.5上没有抛出任何异常。
这是预期的行为吗?我应该怎么做呢?
答案 0 :(得分:2)
如果你在初始化期间启动一个线程,你不知道初始化在另一个线程中已经走了多远。
您注意到不同.Net版本的行为存在差异,但您无法确定不同计算机上的事物顺序。
我使用自己的消息泵解决了Windows窗体中的许多线程问题,使用了队列和普通的Timer控件:
使用此方法会在初始化期间出现后台作业问题,但也会在关闭/处理表单时出现问题,因为只有在表单完全正常运行时才会触发计时器。
答案 1 :(得分:2)
那是因为Close方法关闭了表单并销毁它的句柄,然后在没有句柄的Closed表单中调用MessageBox,因此显示错误消息。
我不了解你的目的,但你应该在关闭调用后移动代码,或者在它们之后移动关闭。例如:
Invoke(new Action(() => {
Hide();
MessageBox.Show("closed in invoke from another thread");
new Form1();
Close();
}));
修改强>
MSDN关于Control.Invoke的说明:
如果当前控件的基础窗口句柄尚不存在,则Invoke方法搜索控件的父链,直到找到具有窗口句柄的控件或窗体。如果找不到合适的句柄,Invoke方法将抛出异常。呼叫期间引发的异常将传播回呼叫者。