这是我想要实现的(不是实际的代码,而是关闭)
private volatile bool isElapsedAlreadyRunningvoID myTimer_Elapsed(object sender,ElapsedEventArgs e){ if (!isElapsedAlreadyRunning) // to prevent reentrance { isElapsedAlreadyRunning = true; try { while (myTimer.Enabled && some other condition) { do stuff } } finally { isElapsedAlreadyRunning = false; } }}myTimer.Start() and myTimer.Stop() are in other methods that can be called frrom other threads
我正在使用System.Timers.Timer类
如果您对此设计有任何其他意见或看到任何陷阱,请随时评论:)
谢谢
编辑:
男人,线程很难.基于答案和其他stackoverflow问题(this answer particularly),这将是这样做的方式(我希望这次没关系)
public class NolockTimer : Idisposable{ private Readonly System.Timers.Timer _timer; private bool _isTimerStopped = false; private Readonly object _isTimerStoppedLock = new object(); public NolockTimer() { _timer = new System.Timers.Timer { autoreset = false,Interval = 1000 }; _timer.Elapsed += delegate { try { while (!IsTimerStopped && some other condition) { // do stuff } } catch (Exception e) { // Do some logging } finally { if (!IsTimerStopped) { _timer.Start(); // <- Manual restart. } } }; _timer.Start(); } public voID Stop() { IsTimerStopped = true; if (_timer != null) { _timer.Stop(); } } private bool IsTimerStopped { get { lock (_isTimerStoppedLock) { return _isTimerStopped; } } set { lock (_isTimerStoppedLock) { _isTimerStopped = value; } } } public voID dispose() { Stop(); if (_timer != null) { _timer.dispose(); } }}解决方法 不,这不安全.在线程池线程上调用Elapsed事件处理程序.您无法预测该线程何时实际调用您的方法,它取决于该进程中正在运行的其他TP线程.在技术上可以同时在飞行中进行两次呼叫.这使得isElapsedAlreadyRunning变量上的volatile关键字不足以确保该方法是线程安全的,您必须使用lock关键字或Monitor.TryEnter().
将Timer的autoreset属性设置为false时,此问题消失.确保在finally块中重新启动计时器,Timer.Elapsed事件的另一个令人讨厌的问题是在没有诊断的情况下吞没异常. System.Threading.Timer是一个全能的更好的计时器,没有像这样的惊喜.
Timer.Enabled属性有类似的问题,你总会看到它迟到.
总结以上是内存溢出为你收集整理的c# – System.Timers.Timer.Enabled属性是否安全,因此可以从计时器的Elapsed事件中访问它?全部内容,希望文章能够帮你解决c# – System.Timers.Timer.Enabled属性是否安全,因此可以从计时器的Elapsed事件中访问它?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)