在后台线程上创建表单并使用Form.ShowDialog

时间:2012-06-05 22:23:23

标签: c# winforms multithreading

使用Winforms, 如果我在一个不是“主要”ui线程的线程上,我可以安全地

  1. 创建表单
  2. 在该表单上调用ShowDialog
  3. 似乎我会遵守以下规则: 必须在创建它们的线程上修改Winforms控件。

    从我所做的一些阅读中,似乎ShowDialog将创建自己的消息泵,这样我就不必担心在已经有消息泵的线程上创建Form。

    问题的背景是我得到一个回调,我想显示一些Winforms UI,但是我没有访问任何其他可以用来调用主线程的UI。

2 个答案:

答案 0 :(得分:7)

这大致是正确的,尽管调用线程的SetApartmentState()方法将线程切换到STA非常重要。对于许多UI操作很重要,包括剪贴板,拖放和shell对话框。当你在线程上创建的表单不在前台并隐藏在另一个窗口后面时,你通常会遇到一个糟糕的Z顺序问题。或者当用户不期望它并且意外地抓住鼠标点击或击键时,实际上的讨厌习惯会在前台移动。

这些都是难以解决的问题,它们确实让你的应用变得片状。没有充分的理由没有引用调用,你也可以通过某种方式将它传递给类。如果真的有必要,你总是让Application.OpenForms [0]重新开始。

答案 1 :(得分:2)

是的,您可以这样做,但如果您希望对话框实际上像一个模态对话框(即阻止父窗口,我假设您想要,因为您正在调用ShowDialog),那么请准备好感到失望。

你真的想在这里解决什么问题。听起来你想要一个不会阻塞的模态对话框,这有点奇怪。如果您解释手头的问题,可能存在一个尚未考虑的解决方案。