计时器之谜 - Forms.Timer与Threading.Timer

时间:2011-08-12 13:44:05

标签: c# timer

今天我遇到了一个非常有趣的问题,我很幸运能够很快解决这个问题,但是我想知道问题的本质。

我编写了一个管理操纵杆操作的控件类。我想开始一些操作并在按钮单击时启动计时器,并在计时器间隔后停止此操作。

我有一个类(伪代码),如下所示:

public class Joystick : UserControl
{
  private Form.Timer timer; //or System.Threading.Timer
  public void Init()
  {
      timer.Tick += new EventHandler(timerCallback)   //Threading.Timer(timerCallback)
      timer.Stop();//timer.Change(Timeout.Infinite, Timeout.Infinite);
  }

   public void ButtonCallback()
   {
      StartSomething();
      timer.Stop();
      timer.Start(); //timer.Change(500, Timeout.Infinite); 
   }   

  public void timerCallback()
  {
     StopSomething();
     timer.Stop();//timer.Change(Timeout.Infinite, Timeout.Infinite);
  }
}

我有两个应用程序,一个是非常简单的(只是一个表单),第二个是更复杂的,但是这个复杂性背后仍然是包含这个UserControl的普通Form(好的DotNetMagicForm)。管理代码在两个应用程序中完全相同,但在更复杂的应用程序中,从未调用过timerCallback()。简单来说,一切都很好。在两种情况下都会调用init(断点)。即使我在ButtonCallback中分配timerCallback - 仍未调用timerCallback。

我遵循了我的同事的建议,并使用Threading.Timer而不是Forms.Timer重写了它,突然它开始在两个应用程序中工作。我们俩都不知道为什么会这样。

我知道我的问题很模糊,但可能是这个问题的根源?

由于

3 个答案:

答案 0 :(得分:5)

Threading.Timer不使用UI消息泵回调刻度线。它使用ThreadPool线程来执行此操作。

UI定时器只是将消息发布到表单的消息泵以请求回调。您的背景魔术形式根本没有收到这些消息。我不知道为什么,也许是因为表单是在没有消息泵的另一个线程上,或者非活动表单也不会处理泵。

答案 1 :(得分:1)

您是否查看了this文章,比较了不同的.NET计时器类

答案 2 :(得分:0)

Windows Forms计时器假设将WM_TIMER发送到消息队列。您的消息队列可能太忙于处理其他Windows消息,或者消息可能尚未首先提交。您可能希望使用像Spy ++这样的工具来弄清楚会发生什么(它应该作为visual studio的一部分安装)。