2010-01-09 26 views
19

我想每10秒鐘從Windows服務(使用C#和.NET完成)調用業務層方法。但是,我不想使用Timer_Elapsed事件,因爲它啓動另一個線程/進程,如果第一個線程/進程仍在運行。我只需要一種單線程方法,因爲對同一業務方法的多次調用會產生不必要的複雜性。如何在不使用定時器的情況下在Windows服務中創建循環

所以我在on_start中添加了do-while循環。我知道這不是正確的方式,因爲它產生了這個過程,如果服務關閉,它將成爲孤兒。

我該如何解決這個問題?

問候, 澤

+0

如果你想只使用一個線程,則循環聽起來像是正確的做法 - 我假設你已經包括調用了Thread.Sleep保證該方法不是在緊密循環中調用的。你能否提供你如何調用業務層方法的細節?如果你正在調用它,那麼這應該會給你想要的結果。 – 2010-01-09 08:57:34

+0

好的謝謝。我正在調用它。但是,我發現即使我關閉了它在任務管理器中運行的服務。 我正在嘗試通過在調用業務方法時切換的標誌,並且除非標誌已被重置,否則不要再次調用它。我希望它能起作用。否則,我會嘗試你所建議的。問題是Business方法讀取和寫入串行端口,直到它獲取數據或超時。 – Chakra 2010-01-09 09:16:02

回答

41

還有另一種獲得定時執行的方法,WaitHandle.WaitOne()方法提供了一個超時參數。這在服務中可以很好地工作,因爲它可以讓您實現在單個方法調用中停止服務的定期執行。模板看起來是這樣的:

Thread Worker; 
    AutoResetEvent StopRequest = new AutoResetEvent(false); 

    protected override void OnStart(string[] args) { 
     // Start the worker thread 
     Worker = new Thread(DoWork); 
     Worker.Start(); 
    } 
    protected override void OnStop() { 
     // Signal worker to stop and wait until it does 
     StopRequest.Set(); 
     Worker.Join(); 
    } 
    private void DoWork(object arg) { 
     // Worker thread loop 
     for (;;) { 
      // Run this code once every 10 seconds or stop right away if the service 
      // is stopped 
      if (StopRequest.WaitOne(10000)) return; 
      // Do work... 
      //... 
     } 
    } 
+0

有沒有人在行動中得到過這個實例? – Junto 2010-10-12 14:26:43

+5

基於上面的代碼,我得到了一個在我公司運行的服務。它工作正常。 – thd 2011-02-27 11:34:55

+0

如果「做功」需要超過10秒鐘,會發生什麼情況? – vampire203 2015-02-27 20:45:51

4

使用一個定時器,但只要你進入定時器處理方法,禁用定時器,使得沒有更多的事件被觸發。在退出處理程序之前,重新啓用計時器。

+0

謝謝。但是,如果我這樣做,它會調用業務方法一次,然後再也不會運行? Business方法依次讀取或寫入串行端口,因此應在一次讀/寫/超時後返回,並在一段時間後重復。 – Chakra 2010-01-09 09:16:47

+0

它@Chakravarthy:提供你重新啓用計時器,在離開處理程序之前,它將繼續運行。 – 2010-01-09 09:22:09

+0

由於處理程序方法是在單獨的線程上調用的,因此理論上可以在禁用定時器之前多次調用它。 – 2010-01-09 09:22:55

4

退房this discussion,尤其是jsw的回答。它提出了一種同步機制來防止同時調用業務邏輯。僅在Elapsed處理程序方法中禁用定時器並不能保證阻止並行調用,因爲處理程序是在單獨的線程上調用的。按照jsw的建議使用鎖,並在同步代碼塊內停止計時器。

或者,您可以使用Timer並將AutoReset屬性設置爲false。這樣,Elapsed事件只會引發一次,您可以手動重置計時器以處理方法結束。

+0

+1。好點。 – 2010-01-09 10:13:46

-1
while(true) 
    { 
    ..do something 
    Thread.sleep(some time or day); 
    } 
-1
Thread thread; 
    private void DoWork(object arg) 
    { 
     while (true) 
     { 
      // Run this code once every 20 seconds or stop if the service is stopped 
      try 
      { 
       Thread.Sleep(20000); 
       //Do work.... 
      } 
      catch(ThreadInterruptedException) 
      { 
       return; 
      } 

     } 
    } 

    protected override void OnStart(string[] args) 
    { 
     // Start the thread 
     thread = new Thread(DoWork); 
     mWorker.Start(); 
    } 

    protected override void OnStop() 
    { 
     // interrupt thread and wait until it does 
     thread.Interrupt(); 
     thread.Join(); 
    } 
相關問題