MessageBoxes 什么时候不模态运行?

When do MessageBoxes not act modally?

我一直认为 MessageBoxes 有点像断点——它们会阻止程序执行,直到用户单击 "OK." 但是,我刚刚发现这是不准确的,我正试图弄清楚什么时候 MessageBoxes会也不会停止执行。

通过 SO(成功)搜索问题的解决方案我发现了这个伪代码:

if (somethingHappened())
{
   timer1.Enabled = false; 
   MessageBox.Show("something happened");              
}
else continue with other stuff ...

行为与此不同:

if (somethingHappened())
{
   MessageBox.Show("something happened"); 
   timer1.Enabled = false;              
}
else continue with other stuff ...

在第一种情况下,计时器停止并显示消息框。在第二种情况下,会显示消息框,但计时器 不会 停止。该程序只是继续其他事情。显然,必须在计时器停止之前单击 MessageBox,但我的程序一直在继续。 (再次调用了事件处理器,又出现了一个MessageBox,陷入死循环。)

那么,在什么情况下 MessageBox 不是真正的模式,在用户响应之前无法停止程序的执行?

是的,MessageBox.Show() 是一个模态 window,执行消息框的线程的执行被有效地阻止,直到 window 关闭。所以你的timer1.enabled代码只在关闭后执行,当然其他线程不受此影响,会继续执行,即使是代表定时器对象执行的代码。

没有非模态 MessageBox.Show() 方法,如果您想要非模态行为,则必须编写自己的消息框表单。

A MessageBox 永远不会停止执行 程序 。它只是停止执行调用它的代码序列。所以在这种情况下:

timer1.Enabled = false; 
MessageBox.Show("something happened");

计时器停止,因为您将 Enabled 设置为 false。但在这种情况下:

MessageBox.Show("something happened"); 
timer1.Enabled = false;

计时器没有停止,因为在您通过 MessageBox 对话框之前,您 还没有Enabled 设置为 false。命令式代码语句按照它们编写的顺序执行。在第一行完成之前,第二行不会执行。

这与应用程序中的其他线程无关。只是调用 MessageBox.

的那个

消息框是模态的。但是为了为其 GUI 提供服务,它运行所谓的模态消息循环。该消息循环拉动调度同步消息,还处理异步消息。喜欢WM_TIMER。后一个事实意味着您的计时器会继续计时。

您调用 MessageBox.Show 并且在对话框关闭之前它不会 return。但是在MessageBox.Show里面是一个处理消息的循环。该消息处理的一部分涉及调用您的计时器事件。由于非终止递归,这很可能导致堆栈溢出。而这正是发生在你身上的事情。

要摆脱这一点的关键是 MessageBox.Show 调度计时器事件(以及其他事件),这可能导致重新进入。