How do I change the interval time in System.Threading.Timer from the callback function of this timer?
Solution 1
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));
Solution 2
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
.
Related videos on Youtube
mrbrooks
Updated on June 04, 2022Comments
-
mrbrooks almost 2 years
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)); } }
-
crypted almost 13 years@Mitch Wheat, that is valid for some good reason, testing for example ?
-
mrbrooks almost 13 yearsMitch, it's just an example. Do not take it to heart. lol
-
Randall Deetz almost 8 yearsplus 1 just because you need it
-
-
James Wilkins about 7 yearsJust for the record, while you can of course use -1 for "Infinite", the docs do say you can use
Timeout.Infinite
, which I think more clearly shows the intention. ;) -
Jon Skeet about 7 years@JamesWilkins: True Will edit. (Although if
Timeout.Infinite
were aTimeSpan
it would be clearer - the docs forTimer.Change(int,int)
mentionTimeout.Infinite
; the docs forTimer.Change(TimeSpan, TimeSpaan)
don't :( -
James Wilkins about 7 yearsYeah, got to love the consistency there, lol. ;) Not surprised at all really, come to expect this, along with other useless doc info.
-
Sarrus about 6 yearsFor infinite value in
Timer.Change(TimeSpan, TimeSpan)
theTimeout.InfiniteTimeSpan
field can be used.