我正在运行一个基本的单线程应用程序。
通常,在调用System.Windows.Forms.MessageBox.Show()
时,可以预期此调用会有效阻止进一步执行,直到此方法返回。
然而,当使用System.Windows.Forms.Timer
时,* 相同的 *主题似乎以某种方式释放自身并且Timer
的{{1}}事件正在触发同样的话题。
到底是怎么回事?我觉得这可能与穿线公寓有关,但我想澄清一下。
作为控制台应用程序以其最简单的形式重新创建,如下所示:
Tick
输出:
线程10已进入
线程10已进入
线程10已进入
线程10已进入
线程10已进入
答案 0 :(得分:6)
当显示模式窗口(如消息框)时,Windows消息泵将继续运行。
如果没有,当你在它前面移动模态窗口时,模态窗口后面的窗口显示将不会被更新。
由于Windows消息仍在被抽取,因此" WM_TIMER"消息仍然会被发送到非前景窗口,因此您将看到您注意到的行为。
需要注意的关键是Windows计时器会导致Windows发布" WM_TIMER"消息进入窗口的事件队列,只要窗口的消息泵正在运行,定时器事件将继续处理。
避免这种重新进入问题的一种常见方法是在处理勾选时禁用计时器。
例如,将您的tick处理代码放入名为handleTimer()
的方法中,然后像这样处理tick:
private void timer_Tick(object sender, EventArgs e)
{
timer.Enabled = false;
try
{
handleTimer();
}
finally
{
timer.Enabled = true;
}
}
(如果发生异常,您可能不希望重新启用计时器,在这种情况下,您不需要上面的try/finally
逻辑。)