我想使用 System.Threading.Timer
执行一次。该计时器应该在不再需要时(即回调触发时)通过调用 Dispose
来确定性地清理。
问题在于回调无法可靠地获取对 Timer
的引用!
System.Threading.Timer timer = null;
timer = new System.Threading.Timer(_ =>
{
Console.WriteLine("Elapsed.");
//Dispose the timer here, but timer might be null!
timer.Dispose(); //BUG
}, null, TimeSpan.FromSeconds(1), TimeSpan.Zero);
当回调触发时,变量 timer
可能不会被初始化。此代码并非在所有情况下都有效,因为它包含竞争条件。
我们如何使用 System.Threading.Timer
创建具有确定性清理功能的一次性计时器?
(创建一次性定时器/延迟的更好方法超出了这个问题的范围。我故意以特定方式提出这个问题。)
最佳答案
更改为 constructor of Timer它只接收一个回调,以便它会在状态参数中传递自己。之后立即使用 Change()
进行设置:
System.Threading.Timer timer = null;
timer = new System.Threading.Timer((state) =>
{
Console.WriteLine("Elapsed.");
// Dispose of the timer here:
((System.Threading.Timer)state).Dispose();
});
timer.Change(TimeSpan.FromSeconds(1), TimeSpan.Zero);
如果您不喜欢使用 state
参数,您也可以像问题中的代码那样使用闭包变量。关键不是用构造函数启动计时器。仅在存储对计时器的引用后启动它。
关于.net - 一次性 System.Threading.Timer 如何 self 处置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27669666/