2012-03-31 85 views
1

我有一個.Net 4.0 C#Windows服務,它產生了連續運行的多個線程。每個線程根據計時器以不同的時間間隔運行。關閉在Windows服務中等待定時器的線程

我想勇退關閉這些線程當服務被關閉。

由於部分線程可能在等待小時做它的處理,我要喚醒他們,並告訴他們退出。

我可以創建這些線程循環定期檢查,在一些間隔一些全局變量少,他們的處理間隔,但我寧願一個信號機制,這將導致他們的計時器過早彈出。

我怎麼能喚醒這些線程等待定時器不使用Thread.Abort的或了Thread.interrupt?

+0

,你不只是使用'Timer'做的工作(而不是使用定時器鎖存工作線程)有什麼特別的原因嗎? – 2012-03-31 17:54:35

+2

一個線程太貴,系統對象沒有任何用處,只能等待幾個小時。您可以從Timer類免費獲得線程。 – 2012-03-31 18:13:22

+0

這是一個現有的服務,目前有一個線程用於不同類型的處理。它目前使用Thread.Abort()和Sleep。我將研究使用Timer和它所產生的線程。 – codezoo 2012-03-31 19:27:02

回答

2

我會假設你有一個很好的理由使用獨立管理的線程做的工作(而不是僅僅做在計時器的事件)。如果是這樣,你想用WaitHandle.WaitAny()並檢查返回值來確定的WaitHandle導致線程進行:

public class ExampleService 
{ 
    private static readonly AutoResetEvent TimerLatch = new AutoResetEvent(false); 
    private static readonly AutoResetEvent ShutdownLatch = new AutoResetEvent(false); 
    private static readonly Timer MyTimer = new Timer(TimerTick); 

    public void Start() 
    { 
     var t = new Thread(DoLoop); 
     t.Start(); 

     MyTimer.Change(0, 500); 
    } 

    public void Stop() 
    { 
     ShutdownLatch.Set(); 
    } 

    private static void TimerTick(object state) 
    { 
     TimerLatch.Set(); 
    } 

    private static void DoLoop() 
    { 
     if (WaitHandle.WaitAny(new[] { TimerLatch, ShutdownLatch }) == 0) 
     { 
      // The timer ticked, do something timer related 
     } 
     else 
     { 
      // We are shutting down, do whatever cleanup you need 
     } 
    } 
} 
+0

這是完美的。謝謝。 – codezoo 2012-03-31 19:27:33

2

可以使用WaitHandle.Waitone有超時和使用事件

if (shutDownEvent.WaitOne(_timeout, false)) 
{ 
    //Shutdown 
} 
else 
{ 
    //timeout so Dowork 
} 
0

根據您的場景,它可能是一個選項,使你產生後臺線程的線程,所以你不必擔心明確關閉它們。

Thread thread = new Thread(DoSomething) 
{ 
     IsBackground = true 
}; 

設置IsBackground爲true,使產生的線程後臺線程,不會從終端停止服務。

從MSDN:

線程可以是一個背景線程或前臺線程。 後臺線程與前臺線程相同,但 後臺線程不會阻止進程終止。一旦所有屬於進程的前臺線程都終止,公共的 語言運行時就會結束進程。任何剩餘的後臺線程 已停止並且未完成。

這當然只是一個選項,如果您正在執行的任何操作可能會中斷並且無需正常關閉(例如,執行一些關鍵的清理工作)。否則,因爲兩個其他答案建議你應該使用WaitHandle,並從主線程發出信號。