我有2个全球System.Windows.Forms.Timer
in my form。两者都在表单的构造函数中初始化。但还没有开始。构造函数启动一个新线程该线程启用并启动两个计时器。显然这就是全部交叉螺纹,但它不会引发任何跨线程异常。但它甚至不起作用。它不会触发Timer.Tick
方法。这是代码:
第一种方法:
在表单构造函数中:
KeepMeAliveTimer = new Timer(); //timer 1
KeepMeAliveTimer.Interval = 15000;
KeepMeAliveTimer.Tick += KeepMeAlive;
timer1 = new Timer(); //timer 2
timer1.Interval = 15000;
timer1.Tick += timer1_Tick;
//started a new thread
在新线程中:
//after performing some tasks, it enables the timers
KeepMeAliveTimer.Enabled = true; //timer 1
KeepMeAliveTimer.Start();
timer1.Enabled = true; //timer 2
timer1.Start();
但它没有触发计时器的滴答事件,甚至没有抛出任何异常。
第二种方法:
但是当我初始化并启用Timers
在同一个线程(主线程)中,它们工作得很好:
KeepMeAliveTimer = new Timer(); //timer 1
KeepMeAliveTimer.Interval = 15000;
KeepMeAliveTimer.Tick += KeepMeAlive;
KeepMeAliveTimer.Enabled = true;
KeepMeAliveTimer.Start();
timer1 = new Timer(); //timer 2
timer1.Interval = 15000;
timer1.Tick += timer1_Tick;
timer1.Enabled = true;
timer1.Start();
现在的问题是;如果没有任何异常,为什么第一种方法不起作用?
Timer 类是线程安全的,但不是您期望的那样。在工作线程上调用 Start() 方法实际上会启动计时器。该类完成创建隐藏窗口的工作,以便它可以调用 SetTimer winapi 函数并在完成时接收 WM_TIMER 消息。
但如果没有人在监听该消息,则无法引发 Tick 事件。你不会的,你肯定没有在该线程上调用 Application.Run() 。因此,您不应该在工作线程上启动计时器。如果需要,请使用 Control.BeginInvoke 在 UI 线程上启动它。
或者使用 System.Threading.Timer 或 System.Timers.Timer,它们不依赖于消息循环。您必须正确互锁,它们的 Elapsed 事件或回调仍在运行another线。这种解决方案往往会产生另一个问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)