Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在回调访问计时器时处理计时器_C#_.net_Multithreading_Timer - Fatal编程技术网

C# 在回调访问计时器时处理计时器

C# 在回调访问计时器时处理计时器,c#,.net,multithreading,timer,C#,.net,Multithreading,Timer,编辑 这是一个简化的例子。我在windows服务中有类似的代码 我有以下代码。当我停止计时器时,如何绝对确保没有出现NullReferenceException。我想更改回调中的计时器,因为我正在做的工作可能需要不同的时间 static Timer timer = null; static void Main(string[] args) { timer = new Timer(TimerCallback, null, 5000, -1); Console.WriteLine(

编辑 这是一个简化的例子。我在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);
    }
}

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

您正在访问共享状态—
计时器
字段。任何对共享状态的多线程访问都必须同步,这就是
锁的作用。这其实相当直截了当:)


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


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

何时何地获得NRE?如果主线程刚刚通过此行
timer=null
,而回调想要这样做:
timer.Change(5000,-1)
@CodeCaster他可以在调用
timer.Change(5000,-1)时获得NRE如果他恰好在正确(或错误)的时刻按下了Return。谢谢。这只是一个简单的例子。这是windows服务的一部分。我试着把重要的部分拿出来,并把它们放在一个问题中。“但是,请注意,您并不是在等待计时器回调完成”:是的,我知道这一点。