Winservice - Timer:同一任务正在并行执行
本文关键字:任务 并行执行 Timer Winservice | 更新日期: 2023-09-27 18:11:03
我做了一个windows - service,它在每个操作之后执行一个操作。我们已经这样声明了计时器:
using System.Timers;
....
Int32 myInterval = 60000 * (Convert.ToInt32(ConfigurationManager.AppSettings["lpInterval"].ToString()));
_myTimer = new Timer();
_myTimer.Interval = myInterval;
_myTimer.Elapsed += new ElapsedEventHandler(TimerElapsed);
//Timer-Tick
private void TimerElapsed(object source, ElapsedEventArgs e)
{ PerformAction(); }
我注意到:如果PerformAction()
需要的时间比interval
长(由于WCF-Services或服务器问题),则启动并执行PerformAction
的新'instance'
。因此,PerformAction
(和parallel
)相互运行两次。
这是什么原因?为什么之前的PerformAction
没有被取消?
PerformAction
正在执行Async
吗?我已经找到了一个解决方案,但我只是不理解的行为…
在你运行动作之前停止计时器,然后在执行动作之后再次启动计时器
private void TimerElapsed(object source, ElapsedEventArgs e)
{
_myTimer.Stop();
PerformAction();
_myTimer.Start();
}
系统。计时器
http://msdn.microsoft.com/en-us/library/system.timers.timer.elapsed (v = vs.110) . aspx
在ThreadPool线程上引发Elapsed事件。如果Elapsed事件的处理时间长于Interval,则该事件可能会在另一个ThreadPool线程上再次引发。在这种情况下,事件处理程序应该是可重入的。
经过的事件可以发生在Dispose或Stop方法被调用之后,或者在Enabled属性被设置为false之后,因为触发经过的事件的信号总是排队等待线程池线程的执行。解决此竞争条件的一种方法是设置一个标志,告诉Elapsed事件的事件处理程序忽略后续事件。
这只是计时器的设计决策。它有许多可能的解决方案,从并行触发事件、排队处理程序直到前一个处理程序完成,到完全跳过特定的事件。设计师选择了这个选项。他们可以很容易地选择另一个,就像某些其他计时器的设计者所做的那样。
至于为什么不取消,非合作取消代码非常危险,而且非常容易出错,并且tick处理程序的实现通常不会觉得有必要实现合作取消(如果他们真的想的话,他们可以使用现有的实现来实现),所以这不是一个实际的选择。