c# – System.Timers.Timer.Enabled属性是否安全,因此可以从计时器的Elapsed事件中访问它?

c# – System.Timers.Timer.Enabled属性是否安全,因此可以从计时器的Elapsed事件中访问它?,第1张

概述我有一个Elapsed方法,我有一个while循环.如果从另一个线程禁用/停止计时器,我希望此循环停止.我可以依赖Elapsed方法中的计时器的Enabled属性,或者我应该创建一个“volatile bool timerEnabled”变量来确定.我的测试显示它没问题,但我想在投入生产之前确定这一点. 这是我想要实现的(不是实际的代码,而是关闭) private volatile bool is 我有一个Elapsed方法,我有一个while循环.如果从另一个线程禁用/停止计时器,我希望此循环停止.我可以依赖Elapsed方法中的计时器的Enabled属性,或者我应该创建一个“volatile bool timerEnabled”变量来确定.我的测试显示它没问题,但我想在投入生产之前确定这一点.

这是我想要实现的(不是实际的代码,而是关闭)

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事件中访问它?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1217914.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存