Dot-Net
Windows 服務 System.Timers.Timer 未觸發
我有一個用 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 服務中的計時器。我已經看到了很多關於這個的意見,它們都分為三類,按頻率降序排列:
- 不要使用
System.Windows.Forms.Timer,因為它不起作用。(這只有意義)- 不要使用
System.Threading.Timer,因為它不起作用,System.Timers.Timer而是使用。- 不要使用
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(); } } }我討厭“醫生,醫生,當我這樣做的時候很痛……”的解決方案,但這是我不得不求助的。對下一個有這個問題的人的意見……