【发布时间】:2011-07-04 11:46:59
【问题描述】:
由于我认为与此处无关的原因,我有一个或多个线程与单个实例 UI(表单)通信。
在工作线程中,我需要报告进度或输入数据或简单的选择。所有这些都来自用户与 UI 的交互,当然,对于 M$ .NET,所有 UI 都在主线程中运行。
显然,我需要处理 UI(主)线程和工作线程之间的线程同步。我通过正确验证InvokeRequired 和公司来做到这一点。
InvokeRequired、IsHandleCreated、IsDisposed 等有很多帖子和文章讨论不连贯和微妙之处,所以我不会谈论它。
我只想说,我的 UI 只是一个表单,应该显示为 modal 或 modeless 表单,具体取决于调用者的意愿。
一个可以UI.Warn( "Warning!" ),而另一个可以UI.Question( "Make a choice:", options... )。
现在考虑以下 M$DN 文档的摘录:
与非模态表单不同,当用户单击关闭表单按钮时,.NET Framework 不会调用 Close 方法...
我从来没有关注过显示为 modal 的表单,但是他们的实现者说它不会被销毁,在关闭(隐藏)后可能会处于不可用状态。
但确实如此!
当表单从ShowDialog( ) 返回时,它的Handle 只是被丢弃,因为相信当再次需要它时,将调用ShowDialog( ) 并重新创建句柄。
我不知道为什么 M$ 的东西需要这样做,但我只是认为我可以让完全相同的表单完美地充当 modal 或 modeless 没有问题。 M$DN 文档没有说它被禁止(或者我喝醉了找不到它)!
嗯,最后它是一种相对简单(和肮脏)的修复方法。
var r = ShowDialog( );
// Handle thrown away aftr "ShowDialog()" supposing the
// next one will recreate it.
if ( !this.IsHandleCreated )
{
// Force "Handle" recreation here, while in the main thread,
// before any "Show()" happens.
CreateHandle( );
}
return r;
它有效,但我想知道它是否不应该是达到同一目的的任何体面的方式。 (也许在一些不携带任何限制祖先兼容性包的东西中进行编程,因为 .NET 仍然如此......)
【问题讨论】:
-
当你说 M$ 时,我不能把你当回事。
-
我猜他只是对MS有点生气-)
-
问题是:我应该如何清洁?有没有合适的方法来做到这一点?
标签: c# multithreading forms dialog invoke