c# - 停止时同步 Timers.Timer elapsed 方法

标签 c# .net synchronization timer

引用来自 MSDN 的引述关于 System.Timers.Timer:

The Timer.Elapsed event is raised on a ThreadPool thread, so the event-handling method might run on one thread at the same time that a call to the Timer.Stop method runs on another thread. This might result in the Elapsed event being raised after the Stop method is called. This race condition cannot be prevented simply by comparing the SignalTime property with the time when the Stop method is called, because the event-handling method might already be executing when the Stop method is called, or might begin executing between the moment when the Stop method is called and the moment when the stop time is saved. If it is critical to prevent the thread that calls the Stop method from proceeding while the event-handling method is still executing, use a more robust synchronization mechanism such as the Monitor class or the CompareExchange method. Code that uses the CompareExchange method can be found in the example for the Timer.Stop method.

谁能举一个“健壮的同步机制,例如 Monitor 类”的例子来解释这到底是什么意思?

我认为这意味着以某种方式使用锁,但我不确定您将如何实现它。

最佳答案

可靠地停止 System.Timers.Timer 确实是一项重大工作。最严重的问题是,由于线程池调度程序算法,它用于调用 Elapsed 事件的线程池线程可能会备份。有几个备用电话并不罕见,拥有数百个在技术上是可能的。

您将需要两次同步,一次确保您仅在没有 Elapsed 事件处理程序运行时才停止计时器,另一次确保这些备份的 TP 线程不会造成任何伤害。像这样:

    System.Timers.Timer timer = new System.Timers.Timer();
    object locker = new object();
    ManualResetEvent timerDead = new ManualResetEvent(false);

    private void Timer_Elapsed(object sender, ElapsedEventArgs e) {
        lock (locker) {
            if (timerDead.WaitOne(0)) return;
            // etc...
        }
    }

    private void StopTimer() {
        lock (locker) {
            timerDead.Set();
            timer.Stop();
        }
    }

考虑将 AutoReset 属性设置为 false。这是另一种方式,Elapsed 事件是从捕获异常的内部 .NET 方法调用的。非常讨厌,您的计时器代码在没有任何诊断的情况下停止运行。我不知道历史,但肯定有另一个 MSFT 的团队对这个烂摊子气呼呼地写了 System.Threading.Timer。强烈推荐。

关于c# - 停止时同步 Timers.Timer elapsed 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4810498/

相关文章:

c# - 在 C# 中将 List<Cookie> 转换为 CookieCollection

c# - 已解析的 JSON 对象的属性为空

python - 在python中监控线程同步

java - 一个线程不会运行,直到另一个线程结束

c# - C# 并发中的共享内存

c# - SQL Server 响应时间不一致

c# - 使用命令将 BMP 文件打印到打印机

c# - 当内容之间没有空格时 GridView 中的对齐问题

.net - 在 Azure 中并行运行的任务数量有限

java - 线程局部变量