c# – 在应用程序/服务关闭/停止之前等待定时器已过事件完成
概要:
在 Windows服务和控制台应用程序我正在调用一个公共库,其中包含定时器,定期触发大约需要30秒钟的操作.不过这样做很好 当服务停止或应用程序退出被调用并且计时器在ElapsedEventHandler中时,我需要服务停止/应用程序退出等待直到事件处理程序完成. 我已经通过在调用定时器停止方法时检查一个Boolean InEvent属性来实现这个功能. 虽然这是功能,但问题是:这是最好的办法吗?是否有更好的方法可以更好地达到这个目的? 另一个问题是我需要避免服务停止请求失败,并显示“服务无法响应停止请求” 这是我的实现 public sealed class TimedProcess : IDisposable { static TimedProcess singletonInstance; bool InEvent; Timer processTimer; private TimedProcess() { } public static TimedProcess Instance { get { if (singletonInstance == null) { singletonInstance = new TimedProcess(); } return singletonInstance; } } public void Start(double interval) { this.processTimer = new Timer(); this.processTimer.AutoReset = false; this.processTimer.Interval = interval; this.processTimer.Elapsed += new ElapsedEventHandler(this.processTimer_Elapsed); this.processTimer.Enabled = true; } public void Stop() { if (processTimer != null) { while (InEvent) { } processTimer.Stop(); } } void processTimer_Elapsed(object sender,ElapsedEventArgs e) { try { InEvent = true; // Do something here that takes ~30 seconds } catch { } finally { InEvent = false; processTimer.Enabled = true; } } public void Dispose() { if (processTimer != null) { Stop(); processTimer.Dispose(); } } } 这就是在OnStart / console应用程序main中调用的方法: TimedProcess.Instance.Start(1000); 这是在服务OnStop和应用程序main(挂起的按键)中如何调用: TimedProcess.Instance.Stop(); 解决方法
可能最简单和最可靠的方法是使用监视器.创建主程序和定时器回调可以访问的对象:
private object _timerLock = new object(); 您的主程序在关闭之前尝试锁定: // wait for timer process to stop Monitor.Enter(_timerLock); // do shutdown tasks here 你的定时器回调也锁定它: void processTimer_Elapsed(object sender,ElapsedEventArgs e) { if (!Monitor.TryEnter(_timerLock)) { // something has the lock. Probably shutting down. return; } try { // Do something here that takes ~30 seconds } finally { Monitor.Exit(_timerLock); } } 主程序一经获取就不应该释放锁. 如果您希望主程序在一段时间后继续关闭,无论是否获得锁定,请使用Monitor.TryEnter.例如,这将等待15秒. bool gotLock = Monitor.TryEnter(_timerLock,TimeSpan.FromSeconds(15)); 如果能够获得锁,则返回值为true. 顺便问一下,我强烈建议您使用System.Threading.Timer而不是System.Timers.Timer.后者阻止例外,最终可能会隐藏错误.如果您的Elapsed事件发生异常,它将永远不会被转义,这意味着您永远不会知道它.有关更多信息,请参阅我的blog post. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |