Dot-Net

Windows 服務 System.Timers.Timer 未觸發

  • December 11, 2011

我有一個用 C# 編寫的 Windows 服務,旨在每隔幾分鐘執行一次任務。我System.Timers.Timer為此使用了 a ,但它似乎永遠不會觸發。我在 SO 和其他地方查看了許多不同的文章,但我沒有看到我的程式碼有什麼問題。

這是我的程式碼,為了清楚起見,刪除了與計時器無關的項目……

namespace NovaNotificationService
{
   public partial class NovaNotificationService : ServiceBase
   {
       private System.Timers.Timer IntervalTimer;
       public NovaNotificationService()
       {
           InitializeComponent();
           IntervalTimer = new System.Timers.Timer(60000);  // Default in case app.config is silent.
           IntervalTimer.Enabled = false;
           IntervalTimer.Elapsed += new ElapsedEventHandler(this.IntervalTimer_Elapsed);
       }

       protected override void OnStart(string[] args)
       {
           // Set up the timer...
           IntervalTimer.Enabled = false;
           IntervalTimer.Interval = Properties.Settings.Default.PollingFreqInSec * 1000;
           // Start the timer and wait for the next work to be released...
           IntervalTimer.Start();
       }

       protected override void OnStop()
       {
           IntervalTimer.Enabled = false;
       }

       private void IntervalTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
       {   // Do the thing that needs doing every few minutes...
           DoWork();
       }
   }
}

我真的為這個而撓頭。任何人都可以發現我做錯了什麼愚蠢的事情嗎?

編輯: 根據建議,我IntervalTimer.Enabled = true;之前IntervalTimer.Start();在服務 OnStart 方法中添加了。這不能解決問題。

我已將文件跟踪日誌記錄添加到服務中以確認一些內部結構,並且我確信 Timer.Enabled 值在 OnStart() 完成時為真。

這是我的解決方法…

在花了太多時間尋找這個問題的答案之後,我發現了各種各樣的文章和部落格,討論了 Windows 服務中的計時器。我已經看到了很多關於這個的意見,它們都分為三類,按頻率降序排列:

  1. 不要使用System.Windows.Forms.Timer,因為它不起作用。(這只有意義)
  2. 不要使用System.Threading.Timer,因為它不起作用,System.Timers.Timer而是使用。
  3. 不要使用System.Timers.Timer,因為它不起作用,System.Threading.Timer而是使用。

基於此,我嘗試了 2。這也是微軟似乎推薦的方法,因為他們說這System.Timers.Timer適合“伺服器應用程序”

我發現它System.Timers.Timer在我的 Windows 服務應用程序中不起作用。因此,我已切換到System.Threading.Timer. 這是一個麻煩,因為它需要一些重構才能使其工作。

這大概是我的工作程式碼現在的樣子……

namespace NovaNotificationService
{
   public partial class NovaNotificationService : ServiceBase
   {
       private System.Threading.Timer IntervalTimer;
       public NovaNotificationService()
       {
           InitializeComponent();
       }

       protected override void OnStart(string[] args)
       {
           TimeSpan tsInterval = new TimeSpan(0, 0, Properties.Settings.Default.PollingFreqInSec);
           IntervalTimer = new System.Threading.Timer(
               new System.Threading.TimerCallback(IntervalTimer_Elapsed)
               , null, tsInterval, tsInterval);
       }

       protected override void OnStop()
       {
           IntervalTimer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
           IntervalTimer.Dispose();
           IntervalTimer = null;
       }

       private void IntervalTimer_Elapsed(object state)
       {   // Do the thing that needs doing every few minutes...
           // (Omitted for simplicity is sentinel logic to prevent re-entering
           //  DoWork() if the previous "tick" has for some reason not completed.)
           DoWork();
       }
   }
}

我討厭“醫生,醫生,當我這樣做的時候很痛……”的解決方案,但這是我不得不求助的。對下一個有這個問題的人的意見……

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