System.Windows.Forms.Timer的同步行为

时间:2014-09-09 05:41:43

标签: c# multithreading winforms timer

根据MSDN博客 http://msdn.microsoft.com/en-us/magazine/cc164015.aspx

  

此计时器类引发的计时器事件与之同步   尊重Windows窗体应用程序中的其余代码。任何代码   驻留在计时器事件处理程序中(对于这种类型的计时器)   class)使用应用程序的UI线程

执行

现在看一下下面的代码

 private void Form1_Load(object sender, EventArgs e)
     {
         timer1.Tick += timer1_Tick;
         timer1.Start();
         Thread.Sleep(10000);
      }

 void timer1_Tick(object sender, EventArgs e)
     {
         textBox1.Text = (Convert.ToInt32(textBox1.Text) + 1).ToString();
     }

我的问题是

为什么在主UI线程处于休眠状态时更新textBox1值。

1 个答案:

答案 0 :(得分:2)

不是。 Tick事件仍将在适当的时间引发,事件处理程序排队。当Sleep调用返回并且您的load事件处理程序完成时,将执行Tick事件处理程序并更新TextBox

请注意,如果在UI线程忙/休眠时多次引发Tick事件,那么一旦事件处理程序空闲,它将被执行多次。

要向自己证明,请尝试以下代码:

private readonly Stopwatch watch = new Stopwatch();

private void Form1_Load(object sender, EventArgs e)
{
    this.timer1.Interval = 15000;
    this.timer1.Tick += timer1_Tick;
    this.timer1.Start();
    this.watch.Start();
    Thread.Sleep(20000);
}

private void timer1_Tick(object sender, EventArgs e)
{
    this.timer1.Stop();
    this.label1.Text = this.watch.Elapsed.ToString();
}

如果Tick事件处理程序在UI线程处于休眠状态时更新了Label,那么您希望Text的{​​{1}}代表约15个秒,因为Label的{​​{1}}有多长。你会看到的是它代表大约20秒,这是UI线程正在睡觉的时间。这表明在Interval调用完成之前,Timer事件处理程序尚未执行。