使用 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() 时,它不会发生。

【问题讨论】:

你可以用一些代码来澄清一下。 codeshowAllScriptsWindow 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()

showdialog()的窗体点击message的按钮后,窗体也关闭了?

如何在winform窗体关闭时结束所有创建的线程

WindowsForm多窗体多窗体传值控件数据绑定--12月8日