2012-02-27 41 views
2

在C#中,當使用System.Timers.Timer時,如果前一個沒有完成,ElapsedEvent可以運行嗎? 想象一下,我有一個事件需要花費更長的時間才能完成,而且計時器的間隔時間已到,在執行完成之前。然後會發生什麼?可以同時運行來自同一個System.Timers.Timer的兩個ElapsedEvent

從我能讀到的MSDN上,System.Timers在線程池上運行,其中Windows定時器運行單線程。 我擔心我會不小心同時運行兩個(或更多!)事件。

回答

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方法並不能保證經過的事件的結束,因爲停止事件可以在不同的線程進行排隊尊重間隔事件。

再次讀取MSDN闡明如何處理這種情況

2

是的,他們可以。

兩個可能的解決方案:

  • 指定的計時器SynchonizingObject以防止多個線程同時運行。這裏的問題是,如果你的實現需要比定時器超時更長的時間,那麼你的調用將會恢復。

  • 在委託開始時停止定時器,並在最後重新啓動它。這似乎是一種更常見的模式,但意味着除非您在回調中進行一些時間安排,否則您的活動不會按時完成。這可能是也可能不是問題。

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屬性來獲取更多的控制
  • 保持某種原子或反說是否要真正過程中的「嘀」
  • 採取某種「流產「行動

......這真的取決於你的情況。

相關問題