我的代码示例:
Timer timer = new Timer(Timer_Tick, null, Timeout.Infinite, Timeout.Infinite);
Mutex timerSync = new Mutex();
void StartWork()
{
timer.Change(0, 1); //Start timer
//Do something...
}
void Dispose()
{
timer.Change(Timeout.Infinite, Timeout.Infinite); //Stop timer
timer.Dispose();
timerSync.Dispose();
//Dispose other things...
}
void Timer_Tick()
{
if (timerSync.WaitOne(0))
{
try
{
//Do something...
}
catch (Exception)
{
//If any exception occurs, abort the "Tick" callback!
return;
}
finally
{
//Whatever happens, release the mutex!
timerSync.ReleaseMutex();
}
}
}
当我停止计时器并处理它时,这不会停止当前的回调,这会产生错误。
特别是,如果正在运行回调,则会得到与互斥锁有关的ObjectDisposedException。
对于执行的结构方式,如果我在“ Dispose”方法上使用该互斥锁,则会导致死锁。
我已经想到了一种解决方案:使用另一个try-catch块来处理与互斥锁有关的异常。
但是我想知道是否有一种方法可以强制取消计时器的任何回调。
答案 0 :(得分:2)
根据文档,您应该使用Dispose(WaitHandle)
重载:
释放当前计时器实例使用的所有资源,并在计时器被处置后发出信号。
此方法完成后,它会发出由
WaitHandle
参数指定的notifyObject
的信号。如果希望能够阻塞,请使用Dispose
方法的重载,直到确定计时器已被处置。在所有当前排队的回调完成之前,不会释放计时器。
void Dispose()
{
timer.Change(Timeout.Infinite, Timeout.Infinite); //Stop timer
var waiter = new ManualResetEvent(false);
timer.Dispose(waiter);
waiter.WaitOne();
waiter.Dispose();
timerSync.Dispose();
//Dispose other things...
}
如果您根本不想等待当前的回调执行,则可以遵循IDisposable
模式:
Timer timer = new Timer(Timer_Tick, null, Timeout.Infinite, Timeout.Infinite);
Mutex timerSync = new Mutex();
private bool _disposed;
void Dispose()
{
_disposed = true;
...
}
void Timer_Tick()
{
if (_disposed)
{
return;
}
...
}