In this post we’re going to see 2 different implementations for executing tasks in a background thread. This is especially useful for keeping the user interface responsive and the user delighted at all times.
I created a small WPF app that starts a background thread just to try out 2 different approaches that both report progress - we don’t want our users left in the dark in regards to how long the operation will take, do we?
Here’s how the app looks like:
Pretty short and simple, huh?
This approach is slightly longer, but it works the same way.
What Microsoft recommends
Here’s what Microsoft has to say about which approach to use:
async-based approach to asynchronous programming is preferable to existing approaches in almost every case. In particular, this approach is better than the
BackgroundWorkerclass for I/O-bound operations because the code is simpler and you don’t have to guard against race conditions. In combination with the
Task.Runmethod, async programming is better than
BackgroundWorkerfor CPU-bound operations because async programming separates the coordination details of running your code from the work that
Task.Runtransfers to the threadpool.
More examples from Stephen Cleary
Stephen Cleary is the Concurrency in C# Cookbook author and he also wrote a series of blog posts where he details the differences between
BackgroundWorker from a few different perspectives: error handling, returning results, cancellation and reporting progress. He arrives at the same conclusion:
async is better than
I hope that this series is sufficient to convince you that
BackgroundWorkeris a type that should not be used in new code. Everything it can do,
Task.Runcan do better; and
Task.Runcan do a lot of things that
Without further ado, I present you the first post in the series. Be sure to check ALL of them: Stephen Cleary: Task.Run vs BackgroundWorker.
The full source code is available on GitHub. You can clone the repo and try it locally.