How do I change the interval time in System.Threading.Timer from the callback function of this timer?

StackOverflow https://stackoverflow.com/questions/6119863

  •  01-01-2021
  •  | 
  •  

Question

How do I change the interval in System.Threading.Timer from the callback function of this timer? Is this correct?

Doing so. Did not happen.

public class TestTimer
{
    private static Timer _timer = new Timer(TimerCallBack); 

    public void Run()
    {
        _timer.Change(TimeSpan.Zero, TimeSpan.FromMinutes(1));
    }

    private static void TimerCallBack(object obj)
    {
        if(true)
            _timer.Change(TimeSpan.Zero, TimeSpan.FromMinutes(10));
    }

}
Était-ce utile?

La solution

This line generate infinite recursion:

if(true)
    _timer.Change(TimeSpan.Zero, TimeSpan.FromMinutes(10));

The first parameter forces TimerCallBack to execute right away. So it executes it again and again indefinitely.

The fix would be

if(true)
    _timer.Change(TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10));

Autres conseils

The problem is that your call to Change specifies that the next call should happen immediately. If you're going to call Change every time, you can just use a period of Timeout.Infinite (which is just a constant of -1) to tell it to avoid repeating at all after the next time - but it will still keep firing, because that next time, you reset it. For example:

using System;
using System.Threading;

static class Program
{
    private static Timer timer = new Timer(TimerCallBack); 

    public static void Main()
    {
        timer.Change(TimeSpan.Zero, TimeSpan.FromSeconds(1));
        Thread.Sleep(10000);

    }

    private static void TimerCallBack(object obj)
    {
        Console.WriteLine("{0}: Fired", DateTime.Now);
        timer.Change(TimeSpan.FromSeconds(3),
                     TimeSpan.FromMilliseconds(Timeout.Infinite));
    }
}

Alternatively, you could change it just once, and then leave it:

using System;
using System.Threading;

static class Program
{
    private static Timer timer = new Timer(TimerCallBack); 
    private static bool changed = false;

    public static void Main()
    {
        timer.Change(TimeSpan.Zero, TimeSpan.FromSeconds(1));
        Thread.Sleep(10000);

    }

    private static void TimerCallBack(object obj)
    {
        Console.WriteLine("{0}: Fired", DateTime.Now);
        if (!changed)
        {
            changed = true;
            TimeSpan interval = TimeSpan.FromSeconds(3);
            timer.Change(interval, interval);
        }
    }
}

Note that nothing is using the initial interval (1 second in the samples above) in either case, because we're calling Change immediately - if you really want a different time before the first call, don't use TimeSpan.Zero in the initial call to Change.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top