在回调访问计时器时释放计时器

本文关键字:计时器 释放 访问 回调 | 更新日期: 2023-09-27 18:23:34

编辑这是一个简化的例子。我在windows服务中有类似的代码。

我有以下代码。当我停止计时器时,我如何确保我不会得到NullReferenceException。我想更改回调中的计时器,因为我正在做的工作可能需要不同的时间。

static Timer timer = null;
static void Main(string[] args)
{
    timer = new Timer(TimerCallback, null, 5000, -1);
    Console.WriteLine("Press enter to exit");
    Console.ReadLine();
    timer.Dispose();
    timer = null;
}
static void TimerCallback(object state)
{
    //do work
    Console.WriteLine("Doing work");
    Thread.Sleep(3000);
    //do I need a lock here? or an if (timer != null)
    timer.Change(5000, -1);
}

我需要这样的锁吗?这是最好的方法吗?

static void Main(string[] args)
{
    timer = new Timer(TimerCallback, null, 5000, -1);
    Console.WriteLine("Press enter to exit");
    Console.ReadLine();
    lock (timerlock)
    {
        timer.Dispose();
        timer = null;
    }
}
static void TimerCallback(object state)
{
    //do work
    Console.WriteLine("Doing work");
    Thread.Sleep(3000);
    lock (timerlock)
    {
        if (timer != null) 
            timer.Change(5000, -1);
    }
}

在回调访问计时器时释放计时器

是的,这是最简单、最安全的方法。

您正在访问共享状态-timer字段。任何对共享状态的多线程访问都必须同步,这就是lock的作用。这真的很直接:)

但是,请注意,您并不是在等待定时器回调完成-如果您的应用程序退出,回调将在中途中止。当然,这可能会给你带来麻烦。

解决这个问题的最简单方法是使用一些信号原语来确保主线程等待回调完成。