在C#中,当使用System.Timers.Timer
时,ElapsedEvent
如果前一个尚未完成,可以运行吗?
想象一下,我有一个事件需要比我预期的更长的时间来完成,并且在执行完成之前计时器的间隔已经达到。那么会发生什么?
从我在MSDN上看到的内容,System.Timers
在线程池上运行,而Windows Timers运行单线程。
我担心我会意外地同时运行两个(或更多!)事件。
答案 0 :(得分:4)
是的,Elapsed事件将再次被触发。 仔细阅读MSDN文档:
If the SynchronizingObject property is Nothing, the Elapsed event is raised on a ThreadPool thread. If the processing of the Elapsed event lasts longer than Interval, the event might be raised again on another ThreadPool thread. In this situation, the event handler should be reentrant.
同样使用Stop方法并不能确保Elapsed事件的结束,因为Stop事件可以在与Interval事件不同的线程中排队。
再次阅读MSDN阐明了如何处理这种情况
答案 1 :(得分:2)
是的,他们可以。
两种可能的解决方案:
在计时器中指定SynchonizingObject
以防止多个线程立即运行。这里的问题是,如果你的实现需要比定时器超时更长的时间,那么你的调用将会备份。
在代表开始时停止计时器,并在结束时再次重新启动计时器。这似乎是一种更常见的模式,但意味着除非你在回调中做一些计时,否则你的事件不会准确地按时发射。这可能是也可能不是问题。
答案 2 :(得分:2)
是的,绝对的。这是一个简短但完整的程序来证明:
using System;
using System.Threading;
using Timer = System.Timers.Timer;
class Test
{
static void Main()
{
Timer timer = new Timer(1000);
timer.Elapsed += ElapsedHandler;
timer.Enabled = true;
Thread.Sleep(10000);
timer.Enabled = false;
}
static void ElapsedHandler(object sender, EventArgs e)
{
int id = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine("{0}: Starting to sleep", id);
Thread.Sleep(5000);
Console.WriteLine("{0}: Exiting", id);
}
}
你如何处理它取决于你。你可以:
SynchronizingObject
属性获取更多控制权......这实际上取决于你的情况。