Dot-Net

執行緒睡眠和 Windows 服務

  • March 9, 2010

我正在開發一個有一些問題的 Windows 服務,Thread.Sleep()所以我想我會嘗試使用計時器,因為這個問題建議:

在 Windows 服務中使用 Thread.Sleep()

問題是我並不完全清楚如何實現這一點。我相信這是方式,但我只是想確保:

'' Inside The Service Object
Dim closingGate As System.Threading.AutoResetEvent

Protected Overrides Sub OnStart(ByVal args() As String)
  Dim worker As New Threading.Thread(AddressOf Work)
  worker.Start()
End Sub

Protected Sub Work()
  Dim Program = New MyProgram()
  closingGate = New System.Threading.AutoResetEvent(False)
  Program.RunService(closingGate)
End Sub

Protected Overrides Sub OnStop()
  closingGate.Set()
End Sub

'' Inside My Programs Code:
Public Sub RunService(closingGate As AutoResetEvent)
  Dim tmr As New Timer
  '' ...and so on

  closingGate.WaitOne()
End Sub

除了使用 VB.Net(開玩笑,但如果可以的話,我會使用 C#。)我在正確的軌道上嗎?這比使用更好Thread.Sleep()嗎?

老實說,我不得不說我認為你在這裡有點偏離正常。

首先,貼出的實際程式碼並沒有真正的意義;工作執行緒無緣無故地等待信號 - 它實際上並沒有處於任何類型的循環中或等待資源。其次,如果您確實需要在收到關閉信號後在工作執行緒中執行一些(可能省略)清理程式碼,您的服務可能沒有給工作執行緒足夠的時間來清理。

但是,更根本的是,您所做的只是將問題轉移到一個單獨的執行緒。這可能會使服務對服務控制器保持響應,但它並不能解決設計問題——而且它通過使用執行緒和互斥體增加了許多不必要的複雜性;最終,如果您需要,它只會使您的服務更難調試。

假設您需要每 5 秒執行一次程式碼。這個想法是,不是“等待” 5 秒,而是反轉控制項,讓計時器呼叫你的工作。

這是不好的:

protected override void OnStart(string[] args)
{
   while (true)
   {
       RunScheduledTasks();    // This is your "work"
       Thread.Sleep(5000);
   }
}

這很好:

public class MyService : ServiceBase
{
   private Timer workTimer;    // System.Threading.Timer

   protected override void OnStart(string[] args)
   {
       workTimer = new Timer(new TimerCallback(DoWork), null, 5000, 5000);
       base.OnStart(args);
   }

   protected override void OnStop()
   {
       workTimer.Dispose();
       base.OnStop();
   }

   private void DoWork(object state)
   {
       RunScheduledTasks();  // Do some work
   }
}

而已。這就是您定期工作所要做的一切。只要工作本身一次不執行幾秒鐘,您的服務將保持對服務控制器的響應。您甚至可以在這種情況下支持暫停:

protected override void OnPause()
{
   workTimer.Change(Timeout.Infinite, Timeout.Infinite);
   base.OnPause();
}

protected override void OnContinue()
{
   workTimer.Change(0, 5000);
   base.OnContinue();
}

您需要開始在服務中創建工作執行緒的唯一時間是工作本身可以執行很長時間並且您需要能夠在中間取消。這往往涉及大量的設計工作,所以我不會在不確定它與您的場景相關的情況下進行討論。

除非您確實需要,否則最好不要開始將多執行緒語義引入您的服務。如果您只是想安排要完成的小型工作單元,那麼您絕對不需要它。

引用自:https://stackoverflow.com/questions/2405619