RollRoll
RollRoll

Reputation: 8462

Why to choose System.Threading over BackgroundWorker?

Why would I decide to choose working directly with System.Threading over BackgroundWorker if the last one abstracts for me the treading managemnet?

I can't see cases where I couldn't use BackgroundWorker to replace System.Threading

Upvotes: 2

Views: 4380

Answers (4)

paparazzo
paparazzo

Reputation: 45096

For one you cannot set scheduling priority on BackgroundWorker but you can on a Thread.

Thread.Priority Property

Comments that question my answer continue to refer to Task and ThreadPool. The stated question is not about Task nor ThreadPool and neither is my answer.

Please refer to the code sample from the link above. It clearly demonstrates assigning priority prior to starting the thread and control over starting the thread.

Complete code sample:

PriorityTest priorityTest = new PriorityTest();
ThreadStart startDelegate =  new ThreadStart(priorityTest.ThreadMethod);

Thread threadOne = new Thread(startDelegate);
threadOne.Name = "ThreadOne";
Thread threadTwo = new Thread(startDelegate);
threadTwo.Name = "ThreadTwo";

threadTwo.Priority = ThreadPriority.BelowNormal;
threadOne.Start();
threadTwo.Start();

// Allow counting for 10 seconds.
Thread.Sleep(10000);
priorityTest.LoopSwitch = false;

I tested this and ThreadTwo starts and finishes on ThreadPriority.BelowNormal. In my test threadOne processes about 10X as threadTwo.

BackGroundWorker has no Priority property. A BackgroundWorker starts with the default priority of Normal. BackgroundWorker thread priority can be changed in DoWork but changing the priority of a thread once the work has started is clearly not the same.

Upvotes: 0

Peter Ritchie
Peter Ritchie

Reputation: 35881

BackgroundWorker has been around since .NET 2.0 and was intended to aid in writing code that will run in a background thread and not bog down the UI thread. It originally appeared with Windows Forms, but also works with WPF or any future UI framework that registers a synchronization context. It allows you to report progress and results back to the UI thread without having to deal with InvokeRequired/BeginInvoke as well supports cancellation.

The Task Parallel Library (TPL) was introduced in .NET 4 and is intended to model asynchronous tasks. These tasks are asynchronous and may or may not be run on another thread. Examples of something that doesn't run on another thread is asynchronous IO and tasks that need to run on the UI (while still being asynchronous). This task metaphor also supports futures (or continuations) so that you can chain tasks together with ContinueWith, sometimes using specific synchronization contexts so that you can do things like run a task on a UI thread (to update the UI, for example).

Tasks also support cancellation and multiple tasks can share a cancellation token so a requested cancellation cancels multiple tasks.

One of the differences is a Task doesn't have an inherent method of reporting progress back to the UI. Of course it's possible, but it's not built into the interfaces. Tasks also support cancellation.

If you only have one thing you want to do in the background and you specifically want to communicate back to a UI like report progress, I would recommend BackgroundWorker. Otherwise I generally recommend using Task<T> (or Task if no result is necessary). Task is inherently used in the C# 5 async/await syntax...

Upvotes: 7

Stephen Cleary
Stephen Cleary

Reputation: 456437

I have a blog post on the subject.

In short, you should use async Tasks if you possibly can. Thread does provide some additional "knobs" - such as Priority - but usually those knobs are not necessary, and programmers often turn them the wrong way anyway.

Upvotes: 2

Lex Li
Lex Li

Reputation: 63143

I hope you attempt to think about the intention of each approaches.

BackgroundWorker was designed for Windows Forms mainly at the very beginning (though it can be used in WPF as well), and it only offers some functionality of asynchronous operation. Compared it to all classes under System.Threading, you can see BackgroundWorker obviously is built upon them.

With all classes under System.Threading, you can build your own BackgroundWorker and enjoy more functionality and control over your code. The difficulty here is sharp learning curve, and debugging challenges.

So if you think BackgroundWorker is enough, keep using it. If you find something missing, building blocks in System.Threading can be your helpers.

In .NET Framework 4, Microsoft designs another set of classes upon System.Threading, named Task-based Asynchronous Pattern,

http://www.microsoft.com/en-us/download/details.aspx?id=19957

Using it, you can almost forget about BackgroundWorker, as it offers much more functionality and give you enough control, while does not require you to dive into the complexity of working with System.Threading directly.

Upvotes: 3

Related Questions