Asynchronous programming in .NET framework has evolved significantly over the years. What is fascinating is the simplicity at which developers can achieve the same goal with the latest async/await implementation in .NET Framework 4.5.
The usage of BackgroundWorker class was hugely popular among developers to offload most of the I/O heavy operations to the background thread to free up the UI for better responsiveness. Even though BackgroundWorker was built based on Thread, the Thread specific implementation was hidden from you making the code less complex than plain thread based implentation. Here we deal with DoWork and RunWorkerCompleted event handlers.
The BackgroundWorker class is essentially built on top of the Thread class. The Thread part of the BackgroundWorker is sort of hidden from you. You get to work with two very important parts of the BackgroundWorker though, the DoWork and RunWorkerCompleted events. As illustrated below, you invoke RunWorkerAsync(you can pass the parameters) which then executes the DoWork handler on a different thread. On completion it triggers the RunWorkerCompleted event handler. You can pass the results via EventArgs.
Note that the DoWork event is executed on a different thread. And more importantly, the RunWorkerCompleted event handler runs in this new thread. When using this in UI (which runs in the main thread), you should take care to avoid cross thread exceptions. Also note how the result and states from DoWork event handler is passed on to RunWorkerCompleted using
Gone are the days of writing those complex code for implementing asynchronous behavior. async and await keywords (C# 5.0) let the implementation of asynchronus operations with much simple code which looks like ‘synchronous coding’. The async and await are based on the Task-based Asynchronous Pattern (TAP) which is the current recommended asynchronous design pattern.
You would agree that the above async/await implementation do not require additional effort to describe or understrood beyond the comments placed there. You get the simlicity of the asynchronous programming and compiler handles the job behind the scenes.
Is that all about the syntax, simplicity? No; Unlike BackgroundWorker, async/await does not create a dedicated thread. Instead it makes use of the threadpool as required and no cross thread worries. Note that it would be wrong to compare BackgroundWorker and async/await as as similar ones. While the former one is specialized component for executing part of the code in the background thread, the latter is more flexible mechanism for implementing asynchronus operations.