繁体   English   中英

从调用内部关闭表格

[英]Closing Form from inside an Invoke

从这样的Invoke内部关闭表单:

Invoke(new Action(() => {
    Close();
    MessageBox.Show("closed in invoke from another thread");
    new Form1();
}));

关闭表单后立即引发异常:

在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke。

但仅在NET 4.0上。 在NET 4.5上,不会引发任何异常。

这是预期的行为吗? 我应该怎么做?

如果在初始化期间启动线程,则不知道初始化在另一个线程中进行了多长时间。

您会注意到不同.Net版本在行为上的差异,但是您无法确定不同计算机上事物的顺序。

我已经使用自己的messagepump,队列和常规Timer控件解决了Windows窗体中的许多线程问题:

  • 将计时器控件添加到窗体中,间隔很小(250毫秒)
  • 将队列添加到您的窗体。
  • 让timer事件使动作出队并执行它。
  • 在初始化甚至其他后台作业期间将操作添加到队列中。

使用此方法将在初始化期间以及在关闭/处置表单期间给后台作业带来问题,因为计时器仅在表单完全起作用时才会触发。

这是因为Close方法关闭了窗体并破坏了它的句柄,然后在没有句柄的Closed窗体中调用了MessageBox,因此显示了错误消息。

我不明白您的目的,但是您应该在“关闭”之后将代码移出调用,或者将“关闭”移到它们之后。 例如:

Invoke(new Action(() => {
    Hide();
    MessageBox.Show("closed in invoke from another thread");
    new Form1();
    Close();
}));

编辑:

有关Control.Invoke的 MSDN注意:

如果当前控件的基础窗口句柄尚不存在,则Invoke方法将向上搜索控件的父链,直到找到具有窗口句柄的控件或窗体。 如果找不到合适的句柄,则Invoke方法将引发异常。 呼叫期间引发的异常将传播回呼叫者。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM