我正在编写一个Windows服务,它每隔一段时间运行一个长度可变的活动(数据库扫描和更新)。我需要频繁运行此任务,但要处理的代码不能同时多次运行。
我如何简单地设置一个计时器来每30秒运行一次任务,同时又不会重叠执行?(我假设System.Threading.Timer
是这项工作的正确计时器,但也可能是错误的)。
发布于 2009-03-26 01:43:59
我会在你的代码中使用Monitor.TryEnter:
if (Monitor.TryEnter(lockobj))
{
try
{
// we got the lock, do your work
}
finally
{
Monitor.Exit(lockobj);
}
}
else
{
// another elapsed has the lock
}
发布于 2009-03-26 03:48:38
对于这样的事情,我更喜欢使用System.Threading.Timer
,因为我不需要经历事件处理机制:
Timer UpdateTimer = new Timer(UpdateCallback, null, 30000, 30000);
object updateLock = new object();
void UpdateCallback(object state)
{
if (Monitor.TryEnter(updateLock))
{
try
{
// do stuff here
}
finally
{
Monitor.Exit(updateLock);
}
}
else
{
// previous timer tick took too long.
// so do nothing this time through.
}
}
您可以通过将计时器设置为一次性计时器并在每次更新后重新启动它来消除对锁的需求:
// Initialize timer as a one-shot
Timer UpdateTimer = new Timer(UpdateCallback, null, 30000, Timeout.Infinite);
void UpdateCallback(object state)
{
// do stuff here
// re-enable the timer
UpdateTimer.Change(30000, Timeout.Infinite);
}
发布于 2009-03-26 03:24:25
而不是锁定(这可能会导致所有定时扫描等待并最终堆叠)。您可以在线程中启动扫描/更新,然后执行检查以查看该线程是否仍处于活动状态。
Thread updateDBThread = new Thread(MyUpdateMethod);
..。
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
if(!updateDBThread.IsAlive)
updateDBThread.Start();
}
https://stackoverflow.com/questions/684200
复制相似问题