MessageBoxes什么时候不采取模态行动?

时间:2015-02-22 20:31:53

标签: c# modal-dialog

我一直认为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 不是是真正的模态,在用户响应之前无法停止执行程序?

3 个答案:

答案 0 :(得分:3)

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

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

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

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

计时器尚未停止,因为在您通过MessageBox对话框后,您尚未Enabled设置为false。命令式代码语句按照它们的写入顺序执行。第二行不会执行,直到第一行完成。

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

的那个

答案 1 :(得分:3)

消息框是模态的。但是为了服务它的GUI,它运行所谓的模态消息循环。该消息循环拉取调度同步消息,并处理异步消息。像WM_TIMER一样。而后一个事实意味着你的计时器继续开火。

你调用MessageBox.Show,直到对话框关闭才真正返回。但是MessageBox.Show内部是一个处理消息的循环。部分消息处理涉及调用计时器事件。由于非终止递归,很可能导致堆栈溢出。这正是发生在你身上的事情。

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

答案 2 :(得分:0)

是的,MessageBox.Show()是一个模态窗口,执行消息框的线程的执行被有效阻止继续,直到窗口关闭。因此,您的timer1.enabled代码仅在关闭后执行,当然其他线程不受此影响并将继续执行,即使是代表计时器对象执行的代码。

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