Aishwarya Shiva
Aishwarya Shiva

Reputation: 3406

Timer vs. repetitive background worker

I am developing a Windows Forms application that calls a WCF service after a specified interval and shows output according to the data received from the service. I had a plan to use timer for this purpose that calls that WCF service method after 500 msec. But some of my colleagues told me to use background worker and then on Work_Completedevent re-run the Worker. I want to know what is the difference between these two? Does timer also creates a background thread? Which one is best suited for long running tasks?

Upvotes: 4

Views: 11898

Answers (4)

Derek
Derek

Reputation: 8628

From MSDN website :-

BackgroundWorker creates a thread on the ThreadPool (via asynchronous delegate invoke). The BCL timers use either a ThreadPool thread to raise the event, or in some cases will raise the tick/elapsed/etc events on the UI thread (in the case of a WinForms timer or a Timers.Timer that has an ISynchronizeInvoke supplied to it).

The BackgroundWorker provides an optimal API for background threads in a UI environment. It allows for a method to run on the background thread (via the DoWork event) and provides a simple way to be notified of progress and completion on the UI thread (ProgressChanged and RunWorkerCOmpleted events) without having to worry about any cross-thread invocation.

The WinForms timer executes on the UI thread and is safe to touch any UI element from its elapsed event. However, you are not guaranteed to execute at exact intervals, it's all dependnet on what's going on on the UI thread. Let me repeat one important thing: there is no background thread with this option!

Threading.Timer is kind of an "ugly API" timer. Timers.Timer simply wraps Threading.Timer into a nicer API and provides a way to automatically invoke the elapsed event on the UI thread (via the SynchronizingObject property). If you set the SynchronizingObject property, no code executes on a background thread, it gets immediately marshalled to the UI thread.

In general, inside a UI, the BackgroundWorker is simply easier to deal with than the other choices.

Upvotes: 6

Keith
Keith

Reputation: 706

In my experience, the main benefit Background Worker is that the ProgressChanged and RunWorkerCompleted events will execute on the same thread that the worker was instantiated on. So, if you start your background worker on your UI thread, the RunWorkerCompleted event will also fire on the UI thread. That makes it so you don't have to worry about making illegal cross-thread calls if you want to update your UI components when your background work completes.

Upvotes: 4

Servy
Servy

Reputation: 203833

A Timer is almost certainly more suitable in terms of resource consumption. A BackgroundWorker is going to create a new thread just for that task. Creating a new thread is a fairly expensive operation. While there are many different timer implementations, and their implementations will vary, they are generally going to be reliant on OS tools that will fire an event periodically, which is going to be preferable to starting up a new dedicated thread.

Most of the key differences in Timer objects is what they do when they're "ready". Some create a new thread pool thread; some have a dedicated thread that is shared by all instances of the timer to run the handler(s), some marshal the code to the UI thread (or some other synchronization context) and it's the latter that you probably want. If you use the timer that is made available in the particular UI framework that you're using it's the behavior that you'll see.

Upvotes: 7

Trevor Elliott
Trevor Elliott

Reputation: 11252

A standard System.Windows.Forms.Timer should be fine. It calls its callback on the UI thread which means that while you are processing inside the callback it will potentially freeze your UI responsiveness. But that's only an issue if you do a lot of work inside the callback or if you block the thread.

To avoid blocking the thread, just execute an asynchronous WCF call.

A BackgroundWorker makes no sense for what you want to do. All you want to do is to wait 500ms before executing some code so just use a System.Windows.Forms.Timer.

Upvotes: 3

Related Questions