如何一次性处理System.Threading.Timer?

时间:2014-12-27 17:27:37

标签: .net timer

我想使用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创建具有确定性清理的一次性计时器?

(创建一次性定时器/延迟的更好方法超出了这个问题的范围。我故意以特定方式询问这一点。)

1 个答案:

答案 0 :(得分:5)

更改为仅接收回调的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参数,您也可以使用闭包变量,就像问题中的代码一样。关键是没有使用构造函数启动计时器。只有在存储了对定时器的引用后才启动它。