- Overview of Asynchrony
- The Old-Fashioned Way: Event-Based Asynchrony
- The Old-Fashioned Way: The Asynchronous Programming Model
- The Modern Way: The Async Pattern
- Getting Started with Async/ Await
- Exception Handling in Async
- Implementing Task-Based Asynchrony
- Cancellation and Progress
- Asynchronous Lambda Expressions
- Asynchronous I/O File Operations in .NET 4.6
- Debugging Tasks
When you go to the restaurant, there are waiters and waitresses ready to serve your table. A waiter takes your order, brings the order to the kitchen, goes to serve another table, and then comes back to your table to bring you your meals. While waiting for you to finish, the waiter does similar operations for other patrons. So, the waiter does not stand at your table from when you arrive until you finish your meal before going to serve another table; if he did, the restaurant would need to hire one waiter per table to avoid the block of their activity, which is not practical. If you compare this real-world description with computer programming, the waiter is some code in your application. If this code must perform a long-running operation and you write such a code in the user interface (UI) thread or, more generally, in one thread, your code will act like a waiter that waits from the start to the end of the meal on a table and cannot do anything else in the meantime, thereby blocking the application activity. This is what happens when you write code in a synchronous approach; synchronous code performs one task at a time and the next task starts only when the previous one completes. To avoid blocking the application, you can use multithreading and instances of the Thread class, described in Chapter 40, “Processes and Multithreading.” With multithreading, you can write code that performs a long-running operation on a separate thread and keep the application responsive. Threading is a way to write asynchronous code that developers have been using for a long time, along with two patterns: the Event-based Asynchronous Pattern and the Asynchronous Programming Model. But actually, asynchrony does not necessarily mean running on a background thread. Instead, it means that a task is executed in different moments. Threading is one way to achieve asynchrony, but it is quite complex and not always the best choice. For this reason, back in .NET 4.5 Microsoft introduced new libraries and new keywords to the Visual Basic and Visual C# languages to make asynchronous calls easy. In this chapter, you get an overview of both the Event-based Asynchronous Pattern and the Asynchronous Programming Model; then you learn about the Asynchronous Pattern, which is without a doubt one of the most important features in Visual Basic language. You will see how easily you can now write modern and responsive applications via asynchronous code.
Overview of Asynchrony
Modern applications often need to perform complex computations or access resources through a network. Complex computations can become very long, a network resource might not be available, or the application might not scale well on the server. If the code that performs this kind of operation is running in the same thread as the caller, the thread gets blocked until all operations complete. If such a thread is the UI thread, the user interface becomes unresponsive and can no longer accept the user input until all operations have been completed. This type of approach is called synchronous because only one operation at a time is executed until all the processes are completed.
Having an unresponsive user interface is not acceptable in modern applications, so this is the place where asynchrony comes in. Asynchrony enables you to execute some pieces of code in a different thread or context, so that the caller thread never blocks. If this is the UI thread, the user interface remains responsive even if other operations are running. The other thread (or context) then tells the caller thread that an operation completed, regardless of the successful or unsuccessful result. The .NET Framework has been offering, for a long time, two thread-based approaches to asynchrony called Event-based Asynchrony and Asynchronous Programming Model in which you launch operations in a different thread and get notification of their completion via delegates. As you saw in Chapter 41, “Parallel Programming and Parallel LINQ,” the .NET Framework 4.0 introduced the Task Parallel Library and the concept of parallelism. TPL makes it easier to create applications capable of scaling long-running operations across all the available processors. TPL also makes applications faster and more responsive while executing complex tasks concurrently, but this all about concurrency, which is not the same as asynchrony. In this chapter, you first learn about the Event-based Asynchrony and the Asynchronous Programming Model to get started with the important concepts; then you start putting your hands on the possibilities offered by the .NET Framework 4.6. By doing so, it will be easier for you to compare the old way to the new way and understand why you should migrate your exiting code to use the new patterns.