Question

Suppose I have a non-recurring event that needs to be raised X seconds from now such as a timeout. Intuitively it would make sense to create a System.Timers.Timer, set its interval to X*1000, wire its tick up to the event and start it. Since this is a non-recurring event and you only want it raised once you would then have to stop the timer after it ticks.

The fact that Timers are inherently recurring however makes me distrustful if this is indeed the best way of doing it. Would it be better/more accurate/safer to save the time started, set the timer to tick every second (or even millisecond) and on tick poll the system for time and manually raise the target event only once the requisite time has elapsed?

Can anyone weigh in on which if either method is best (perhaps there is another option I didn't think of too). Does one method become better than the other if the timespan that I need to wait is measured in milliseconds?

Was it helpful?

Solution

This constructor for the System.Threading.Timer allows you to specify a period. If you set this parameter to -1, it will disable periodic signaling and only execute once.

public Timer(
    TimerCallback callback,
    Object state,
    TimeSpan dueTime,
    TimeSpan period
)

OTHER TIPS

just use a normal timer and disable it after it has elapsed once. that should solve your problem.

both, system.threading.timer and system.timers.timer support this.

Spin off a new BackgroundWorker, sleep, close.

var worker = new BackgroundWorker();
worker.DoWork += delegate {
  Thread.Sleep(30000); 
  DoStuff();
} 
worker.RunWorkerAsync();

You can use a System.Timers.Timer with AutoReset = true, or a System.Threading.Timer with an infinite period (System.Threading.Timeout.Infinite = -1) to execute a timer once.

In either case, you should Dispose your timer when you've finished with it (in the event handler for a Timers.Timer or the callback for a Threading.Timer) if you don't have a recurring interval.

just set it to tick after X seconds, and in the code of the tick, do:

timer.enabled = false;

worked for me.

If you want an accurate time measure, you should consider doubling the timer frequency and using DateTime.Now to compare with your start time. Timers and Thread.Sleep aren't necessarily exact in their time measurements.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top