2012-03-06 64 views
2

我有这个窗体窗体,timer1已启用,它的间隔设置为2000毫秒。 为什么表单每2秒显示一个消息框?我的意思是,当第一次计时器滴答声称UI线程将等待,直到按下确定按钮,所以如果我不按下按钮,所以不应该出现另一个消息框。但它看起来!为什么?Windows窗体计时器vs单线程应用程序

我知道计时器在它自己的线程上工作,并且计时器在它的间隔上调用timer_tick函数,问题是如何在mbox.show()上阻塞UI线程时显示另一个消息框?

public partial class Form1 : Form 
    { 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void timer1_Tick(object sender, EventArgs e) 
    { 
     MessageBox.Show("test"); 
    } 
    } 

回答

3

这是因为你使用的MessageBox。这是一个模式对话框,用于抽取消息循环。因此,所有正常的Windows通知仍然提供。像油漆事件一样。它唯一阻止的是用户输入通知,鼠标和键盘。但是不是一个定时器消息。 Form.ShowDialog()方法也以这种方式工作。

你将不得不自己禁用计时器。

+2

+1有很好的解释。 – 2012-03-06 12:38:31

2

定时器创建自己的工作线程,它不等待确定按钮,因为它做主UI线程。

请尝试以下操作,它工作吗? (不能检查现在后悔)

private void timer1_Tick(object sender, EventArgs e)  
{  
    timer.Stop(); 
    MessageBox.Show("test");  
    timer.Start(); 
} 

编辑:回答在评论

的问题,所以如果主UI线程停在mbox.Show()为什么另一个消息框 显示?

this SO post

MessageBox.Show将显示它的线程从呼吁UI。如果 尚不是线程上运行的消息泵,则它将设置为临时性的 以便运行。在 显示通话结束

+0

所以如果主UI线程停在mbox.Show()为什么另一个消息框显示? – HPT 2012-03-06 12:20:53

+0

查看更新(编辑部分) – sll 2012-03-06 12:52:28

0

定时器工作在它自己的线程不在UI线程所以它不会被消息框对话后,它会撕裂下来。

您可以使用反射器来看看它是如何工作的。

+0

我知道计时器在它自己的线程上工作,并且计时器在它的间隔上调用timer_tick函数,问题是当在mbox.show()上阻塞UI线程时如何显示另一个消息框? – HPT 2012-03-06 12:23:50

0

您需要停止计时器显示的消息框时,当对话框关闭重启:

private void timer1_Tick(object sender, EventArgs e) 
{ 
    this.timer.Stop(); 
    DialogResult result = MessageBox.Show("test"); 
    if (result == DialogResult.OK) 
    { 
     this.timer.Start(); 
    } 
}