Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare using Thread.Sleep and Timer for delayed execution

I have a method which should be delayed running for a specified amount of time.

Should I use

Thread thread = new Thread(() => {     Thread.Sleep(millisecond);     action(); }); thread.IsBackground = true; thread.Start(); 

Or

Timer timer = new Timer(o => action(), null, millisecond, -1); 

I had read some articles about using Thread.Sleep is bad design. But I don't really understand why.

But for using Timer, Timer has dispose method. Since the execution is delayed, I don't know how to dispose Timer. Do you have any suggestions?

Or if you have alternative codes for delayed execution are also appreciate.

like image 797
Chaowlert Chaisrichalermpol Avatar asked Dec 24 '08 15:12

Chaowlert Chaisrichalermpol


People also ask

Is Task delay better than thread sleep?

delay will not and has a cancellation token, unless your app is pretty complex, it really doesn't matter as on the surface: task. delay and thread. sleep do pretty much the same thing. "both do the same thing, they block the executing thread..." -- AFAIK the await task.

Why thread sleep is not recommended?

If given a wait of 5000 Milliseconds(5 seconds) and an element just take just 1-2 seconds to load, script will still wait for another 3 seconds which is bad as it is unnecessarily increasing the execution time. So thread. sleep() increases the execution time in cases where elements are loaded in no due time.

Why thread sleep is not recommended Java?

Thread. sleep is bad! It blocks the current thread and renders it unusable for further work.

How accurate is thread sleep?

Incredibly inaccurate. You have to deal with the inconsistencies of the OS process scheduler, the time spent context switching, the Java VM, etc. Well documentation is silent on its accuracy- it talks a lot about accuracy for System.


1 Answers

One difference is that System.Threading.Timer dispatches the callback on a thread pool thread, rather than creating a new thread every time. If you need this to happen more than once during the life of your application, this will save the overhead of creating and destroying a bunch of threads (a process which is very resource intensive, as the article you reference points out), since it will just reuse threads in the pool, and if you will have more than one timer going at once it means you will have fewer threads running at once (also saving considerable resources).

In other words, Timer is going to be much more efficient. It also may be more accurate, since Thread.Sleep is only guaranteed to wait at LEAST as long as the amount of time you specify (the OS may put it to sleep for much longer). Granted, Timer is still not going to be exactly accurate, but the intent is to fire the callback as close to the specified time as possible, whereas this is NOT necessarily the intent of Thread.Sleep.

As for destroying the Timer, the callback can accept a parameter, so you may be able to pass the Timer itself as the parameter and call Dispose in the callback (though I haven't tried this -- I guess it is possible that the Timer might be locked during the callback).

Edit: No, I guess you can't do this, since you have to specify the callback parameter in the Timer constructor itself.

Maybe something like this? (Again, haven't actually tried it)

class TimerState {     public Timer Timer; } 

...and to start the timer:

TimerState state = new TimerState();  lock (state) {     state.Timer = new Timer((callbackState) => {         action();         lock (callbackState) { callbackState.Timer.Dispose(); }         }, state, millisecond, -1); } 

The locking should prevent the timer callback from trying to free the timer prior to the Timer field having been set.


Addendum: As the commenter pointed out, if action() does something with the UI, then using a System.Windows.Forms.Timer is probably a better bet, since it will run the callback on the UI thread. However, if this is not the case, and it's down to Thread.Sleep vs. Threading.Timer, Threading.Timer is the way to go.

like image 194
Eric Rosenberger Avatar answered Nov 03 '22 08:11

Eric Rosenberger