【发布时间】:2016-02-03 16:52:53
【问题描述】:
在以下 C# 代码中,System.Timers.Timer.Stop 从计时器线程调用,但也从 UI 线程调用:
private void StartTimer()
{
// This is in the context of the UI thread.
this.m_timer = new System.Timers.Timer(1000);
this.m_timer.Elapsed += (sender, e) =>
{
// This is in the context of the timer thread.
try
{
this.m_timer.Stop();
// Do some stuff.
this.m_timer.Start();
}
catch (Exception exception)
{
CTrace.Exception(this, "StartTimer", exception);
}
};
this.m_timer.Start();
}
// After returning from the StartTimer() method, this.m_timer.Stop()
// will be called from the UI thread.
从定时器线程调用System.Timers.Timer.Start 和System.Timers.Timer.Stop 安全吗?它是线程安全的吗?
谢谢!
【问题讨论】:
-
是的,this.m_timer.Stop()可以从Elapsed回调的线程中调用,没关系。需要注意的一件事是,如果“// Do some stuff”代码与 UI 交互,那么您必须在 UI 线程上调用/BeginInvoke。
-
它是线程安全的,没有任何东西会爆炸和冒烟。实际上,确保 Elapsed 事件不再运行通常是不可能的,它可能已被安排在调用 Stop() 之前一微秒在线程池线程上运行。当然,您的将再次启用计时器,因此它将无法正常工作。改用 System.Threading.Timer,它的 Dispose(WaitHandle) 重载提供了互锁保证。
-
@HansPassant 我不同意,两次调用
Stop()与设置两次Enabled = false相同。如果两个线程同时在if(timer != null)块中但有1+ 行分开,this line 是否应该抛出空引用异常?
标签: c# multithreading timer