使用 form.ShowDialog() 时,主窗体中的线程不起作用
Posted
技术标签:
【中文标题】使用 form.ShowDialog() 时,主窗体中的线程不起作用【英文标题】:When using form.ShowDialog() a thread in mainform doesn't work 【发布时间】:2011-03-29 20:01:24 【问题描述】:我有一个使用 form.showDialog() 显示的表单,在主表单中我有一个线程每 x 秒发送一条消息。我注意到,当我在刚刚打开使用 ShowDialog 打开的新表单的窗口中时,线程没有运行。即使使用 ShowDialog,如何让它继续运行?
代码:
codeshowAllScriptsWindow window = new showAllScriptsWindow(this);
window.Show();
在主窗体中,我有一个线程不断发送消息,但由于此显示对话框而停止。请注意,当我使用 show() 时,它不会发生。
【问题讨论】:
你可以用一些代码来澄清一下。code
showAllScriptsWindow window = new showAllScriptsWindow(this); window.Show();code
\b 并且在主窗体中我有一个线程不断发送消息,但由于这个 showdialog 而被停止 - 不是当我使用 show() 时它不会发生。
【参考方案1】:
ShowDialog() 是一个阻塞调用。该线程实际运行,它正忙于为对话框抽出消息循环。这与程序主线程上发生的情况没有什么不同。
这样做是非常不明智的,对话框与应用程序中的其余窗口没有 Z 顺序关系。一个经典的事故是它可能会消失在另一个窗口后面,但用户没有找到找回它的好方法。改为使用 Control.BeginInvoke 在 UI 线程上创建对话框。这也确保您的线程保持“运行”。
【讨论】:
【参考方案2】:消息泵被您正在显示的模式对话框“窃取”。 你有两个选择:
-
不要使用模式对话框(使用 formShow())
使用新线程完成工作并将主线程用于 UI。
【讨论】:
【参考方案3】:虽然乍一看似乎无关,但你可以看看这个question。您遇到的问题是 form.showDialog() 调用创建了一个模式对话框,停止了该线程上的代码进程。如果您旋转另一个线程并在那里触发该调用,您的第一个线程将继续运行,如对话框显示。
【讨论】:
【参考方案4】:使用 System.Threading.Timer 而不是 System.Windows.Form.Timer。
【讨论】:
模态消息泵将使计时器的选择变得无关紧要。 通过 SWF Timer 使用消息泵。但是,使用 System.Threading Timer 不会使用泵,因此模型对话框不会阻止它引发事件。 很公平,吸取了教训。我已经习惯了所有计时器都基于 WM_TIMER 的世界。 我没有使用内置计时器,而是每隔 x 秒从服务器发送一条消息,客户端需要对其进行响应。以上是关于使用 form.ShowDialog() 时,主窗体中的线程不起作用的主要内容,如果未能解决你的问题,请参考以下文章
从 TabControl 拖动时出现表单 ShowDialog 问题
对于Gtk #Windows,是否有Form.Showdialog等价物?
Application.Run()和Form.Show()以及Form.ShowDialog()