I would like to execute a certain method at a given interval. The reason why I can't use a timer + its event handler right away is because I want to add an offset to each tick (100ms in my example below).
It seems to be working just as intented. The reason why I'm starting it manually is because if the _action();
takes more than the given tick time, I want to let it finish before starting a new "tick".
Perhaps this could be done in a much simpler way. I would like your thoughts on the code:
class RandomIntervalTask : IDisposable
{
private readonly Timer _timer;
private readonly int _initialInterval;
private readonly int _range;
private readonly Action _action;
public RandomIntervalTask(int initialInterval, int range, Action action)
{
this._range = range;
this._initialInterval = initialInterval;
this._action = action;
_timer = new Timer { AutoReset = false, Interval = initialInterval };
_timer.Elapsed += TimerElapsed;
_timer.Start();
}
private void TimerElapsed(object sender, ElapsedEventArgs e)
{
var rnd = new Random();
_timer.Interval = rnd.Next(_initialInterval, _initialInterval + _range);
_action();
_timer.Start();
}
public void Dispose()
{
_timer.Stop();
_timer.Dispose();
}
}
Executed like this:
var rit = new RandomIntervalTask(400, 100, DoStuff);
private void DoStuff()
{
Debug.WriteLine("stuff");
}
IDisposable
(really my C#) is a little weaker than I like, but isn't that Dispose implementation open to a problem with a second call calling_timer.Stop()
after_timer.Dispose()
? \$\endgroup\$_timer.Dispose(); _timer = null;
yesterday, and checked if the timer is not null before starting it in the event handler. Otherwise the last tick could run on a disposed timer. This should also take care of your issue. Thanks for the feedback. \$\endgroup\$