1

我有这个代码:

    private void timer1_Tick(object sender, EventArgs e)
    {
        MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString());
    }

定时器已启用,间隔 = 100。

这会导致无限数量的消息框彼此重叠出现,而我原本希望它们只是阻止下一个事件,直到当前消息框关闭。

在更复杂的应用程序中,这可能会导致不可预测的结果,并且好像有多个线程可以访问同一个函数,但实际上它是同一个线程。

为什么会这样?

4

2 回答 2

2

消息框是一个模式对话框,用于抽取消息队列。这样就可以触发计时器滴答消息,因为它们被发布到 GUI 线程的消息队列中。

对于 GUI 线程中显示的模式对话框,情况总是如此。由于每个线程只有一个消息队列,模态对话框的消息泵将提取计时器滴答消息。

于 2013-02-01T19:44:43.580 回答
1

它正在按照它应该的方式发生。滴答事件由消息循环提供支持(除非您使用线程变体),除非您以某种方式(思考Thread.Sleep或非基于消息的代码执行)阻止消息循环,否则将重复调用该事件。

消息框不会阻塞,它只是另一个窗口,只要应用程序的消息泵正常工作,窗口也会正常工作,因此每次滴答发生时,都可以创建和堆叠新对话框。

对此的快速解决方案如下:

private void timer1_Tick(object sender, EventArgs e)
{
    timer1.Stop();
    MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString());
    timer1.Start();
}

这将停止计时器,显示对话框并允许计时器在对话框关闭后恢复。这意味着您只会得到一个对话框,而不是它们的永久堆栈。

于 2013-02-01T19:45:36.040 回答