簡體   English   中英

關閉等待Windows服務中的計時器的線程

[英]Shutdown a thread waiting on a timer in a Windows Service

我有一個.Net 4.0 C#Windows服務,它產生了許多連續運行的線程。 每個線程基於計時器以不同的間隔運行。

我想在服務關閉時正常關閉這些線程。

由於其中一些線程可能需要等待數小時來處理,我需要將它們喚醒並告訴它們退出。

我可以在這些線程中創建一個循環來定期檢查一些全局變量,其間隔時間小於它們的處理間隔,但我更喜歡一種信號機制,它會導致計時器過早彈出。

如何在不使用Thread.Abort或Thread.Interrupt的情況下喚醒這些線程等待計時器?

我將假設您有充分的理由使用獨立管理的線程來完成工作(而不是僅僅在計時器的事件中執行)。 如果是這樣,您希望使用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
        }
    }
}

您可以使用WaitHandle.Waitone超時並使用事件

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

根據您的情況,可能會選擇使您生成后台線程的線程,這樣您就不必擔心明確地將它們關閉。

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

IsBackground設置為true會使生成的線程成為后台線程,該線程不會阻止您的服務終止。

來自MSDN:

線程是后台線程或前台線程。 后台線程與前台線程相同,除了后台線程不會阻止進程終止。 一旦屬於進程的所有前台線程終止,公共語言運行庫就結束該進程。 任何剩余的后台線程都會停止並且不會完成。

這當然只是一個選項,如果你正在執行的任何操作可能被中斷而不必優雅地關閉(例如,做一些關鍵的清理工作)。 否則,因為其他答案都建議你應該使用WaitHandle ,並從主線程發出信號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM