今天我遇到了一个非常有趣的问题,我很幸运能够很快解决这个问题,但是我想知道问题的本质。
我编写了一个管理操纵杆操作的控件类。我想开始一些操作并在按钮单击时启动计时器,并在计时器间隔后停止此操作。
我有一个类(伪代码),如下所示:
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重写了它,突然它开始在两个应用程序中工作。我们俩都不知道为什么会这样。
我知道我的问题很模糊,但可能是这个问题的根源?
由于
答案 0 :(得分:5)
Threading.Timer
不使用UI消息泵回调刻度线。它使用ThreadPool
线程来执行此操作。
UI定时器只是将消息发布到表单的消息泵以请求回调。您的背景魔术形式根本没有收到这些消息。我不知道为什么,也许是因为表单是在没有消息泵的另一个线程上,或者非活动表单也不会处理泵。
答案 1 :(得分:1)
您是否查看了this文章,比较了不同的.NET计时器类
答案 2 :(得分:0)
Windows Forms计时器假设将WM_TIMER发送到消息队列。您的消息队列可能太忙于处理其他Windows消息,或者消息可能尚未首先提交。您可能希望使用像Spy ++这样的工具来弄清楚会发生什么(它应该作为visual studio的一部分安装)。