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
调度计时器事件(以及其他事件),这可能导致重新进入。
我一直认为 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
调度计时器事件(以及其他事件),这可能导致重新进入。