And*_*ndy 6 .net c# synchronization timer
参考MSDN关于System.Timers.Timer的这句话:
Timer.Elapsed事件是在ThreadPool线程上引发的,因此事件处理方法可能在一个线程上运行,同时调用Timer.Stop方法在另一个线程上运行.这可能导致在调用Stop方法后引发Elapsed事件.通过将SignalTime属性与调用Stop方法的时间进行比较,无法阻止此竞争条件,因为事件处理方法可能在调用Stop方法时已经执行,或者可能在Stop方法之间开始执行被调用以及保存停止时间的时刻.如果在事件处理方法仍在执行时阻止调用Stop方法的线程继续运行至关重要,请使用更强大的同步机制,例如Monitor类或CompareExchange方法.使用CompareExchange方法的代码可以在Timer.Stop方法的示例中找到.
任何人都可以举一个" 强大的同步机制,如Monitor类 "来解释这意味着什么?
我认为这意味着以某种方式使用锁,但我不确定如何实现它.
Han*_*ant 12
可靠地停止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();
}
}
Run Code Online (Sandbox Code Playgroud)
考虑将AutoReset属性设置为false.这是另一种方式,Elapsed事件从一个捕获异常的内部.NET方法调用.非常讨厌,你的计时器代码停止运行,没有任何诊断.我不知道历史,但是MSFT的其他团队肯定已经在这个烂摊子里喘不过气来,写了System.Threading.Timer.强烈推荐.
| 归档时间: |
|
| 查看次数: |
6069 次 |
| 最近记录: |