2011-12-29 104 views
1

我有一些代码在定时器事件处理程序有这个定时器在C#中运行一次,那么X秒运行后再次

void timer_Tick(object sender, EventArgs e) 
{ 
    try 
    { 
     timerRescan.Stop(); 
     ScanForIeInstances() 
    } 
    catch (Exception ex) 
    { 
     log.Warn("Exception 3", ex); 
    } 
    finally 
    { 
     timerRescan.Start(); 
    } 
} 

自然存在与谁可能要停止计时器下对外部实体的竞争条件....如果定时器正在处理并使用线程并且有人调用timerRescan.Stop,则定时器线程将调用Start,启动定时器再次返回。我正在尝试替换此代码。在Java中两个方法我知道,我想知道如何在C#一举两得

  1. 运行任务每5秒,其中5秒发射
  2. 运行任务,并在其后的任务之间的距离结束+ 5秒再次运行任务

我想使用#2并始终从事件的最后一次触发结束5秒钟开始。我该怎么做,我在C#中使用哪个计时器?

然后,这允许我有一个循环计时器,一次调用启动,并没有与停止竞争条件(我宁愿不必实现同步,虽然我知道我可以做到这一点作为最后的手段...宁愿只要保持代码干净像我可以在Java)

,或者如果你知道java的,有什么我只是在寻找是 ScheduledExecutorService.scheduleAtFixedRate相当于 - 开始启动 ScheduledExecutorService.scheduleWithFixedDelay - 年底开始

+0

你认为Quartz.NET? http://quartznet.sourceforge.net/ – 2011-12-30 00:01:58

+0

如果Quartz.NET对于您的需求来说太重了,是不是Timer.AutoReset属性打算为您做什么? – 2011-12-30 00:29:33

+0

在石英列表上询问,但列表中的其他人表示他们没有。 – 2012-01-03 16:23:14

回答

2

一个快速的方法处理这个问题是让外部实体设置一个标志,然后检查该标志是否已设置:

public bool StopRequested {get; set;} 

void timer_Tick(object sender, EventArgs e) 
{ 
    if (timerRescan != null) timerRescan.Stop(); 
    if (StopRequested) return; 
    try 
    { 
     ScanForIeInstances() 
    } 
    catch (Exception ex) 
    { 
     log.Warn("Exception 3", ex); 
    } 
    finally 
    { 
     timerRescan.Start(); 
    } 
} 

如果外部实体具有定时器的句柄,但是定时器应该可能是私人的,这并不能解决问题。

+0

我一直希望避免这些工作,并删除代码以保持它在Java中的清洁,唉,好吧。 – 2012-01-03 16:22:20

0

如果你唯一担心的是,外部源可能要停止计时,最好的办法是写解决此计时器,检查各种信号灯的包装....

我没有做过任何测试这一点,但你应该能够掌握一般想法。

public class TimerWrapper 
{ 
    public event EventHandler Elapsed; 
    private System.Timers.Timer timer; 
    private System.Threading.ManualResetEvent stopped; 
    private object lockObject = new object(); 

    public TimerWrapper(double interval) 
    { 
    stopped = new System.Threading.ManualResetEvent(false); 
    timer = new System.Timers.Timer(interval); 
    timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); 
    timer.Start(); 
    } 

    void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
    { 
    lock (lockObject) 
    { 
     timer.Stop(); 
     try 
     { 
     Elapsed(this, new EventArgs()); 
     } 
     finally 
     { 
     if (!stopped.WaitOne(0)) timer.Start(); 
     } 
    } 
    } 

    public void Start() 
    { 
    stopped.Reset(); 
    lock (lockObject) 
    { 
     timer.Start(); 
    } 
    } 

    public void Stop() 
    { 
    stopped.Set(); 
    lock (lockObject) 
    { 
     timer.Stop(); 
    } 
    } 
} 
相关问题