Asynchronous Programming Patterns in .NET C#

C# Programming Tutorials

In today’s era of modern programming technologies, it is crucial for developers to know the techniques and principles of Asynchronous programming. If you are familiar with building a website or even a class library in .NET C#, you have probably used Asynchronous counterparts or methods in your applications. In this .NET programming tutorial, we focus on the Task-based Asynchronous Pattern (TAP), which is recommended for modern application development methodologies. Before we dive into TAP, however, let us briefly see what the different Asynchronous patterns .NET offers are.

Read: Best Online Courses to Learn C#

What are the .NET Asynchronous Patterns?

.NET provides three Asynchronous programming patterns. They include:

  • Task-based Asynchronous Pattern (TAP): Since the advent of .NET 4.0, the recommended Asynchronous model in .NET is the Task-based Asynchronous (TAP) model. C# supports TAP through the async and await keywords. In TAP, a single method represents both the initiation and completion of an Asynchronous operation.
  • Event-based Asynchronous Pattern (EAP): EAP was introduced in .NET 2. It represents the event-based legacy model for performing Asynchronous operations. It uses the async keyword and event-handler delegate types. The pattern is no longer recommended for new .NET application development.
  • Asynchronous Programming Model (APM): This is a legacy model that uses the IAsyncResult interface for providing Asynchronous operations. The pattern uses Begin and End methods for implementing Asynchronous behaviour. This pattern is also no longer recommended for new application development.

Task-based Asynchronous Pattern (TAP)

TAP is included in the System.Threading.Tasks namespace and is used to represent the arbitrary Asynchronous action of the code. As its name implies, it is related to a task-based approach. Here, you can think of a ‘Task’ as a process running in the background, either sequentially or in parallel. This Asynchronous model is based on the Task class, which is a representation of the Task Parallel Library (TPL) in C#.

Asynchronous Methods in Task-based Asynchronous Pattern (TAP)

The Task-based Asynchronous Pattern uses the async suffix with the name of the method that returns awaitable types, such as Task, Task, ValueTask, and ValueTask.
For example, developers can implement TAP to achieve the error-handling mechanism in C# in the following ways:

try
{
    var firstResult = await Task.Run(() => DoMultiplication(7,2));
    var secondResult = DoAnotherCalculation(firstResult);
}
catch (TaskCanceledException)
{
    await HandleCancelation();
}
catch (Exception exception)
{
    await HandleError(exception);
}

Read: Unit Testing Asynchronous Code in C#

What are the Use cases of C# Asynchronous Methods?

There are many use cases for Asynchronous methods in C#. For instance, If a programmer is going to run multiple tasks concurrently, they can do so in the following C# code example:

var backgroundTasks = new[]
{
    Task.Run(() => DoMultiplication(7,1)),
    Task.Run(() => DoMultiplication(8,4)),
    Task.Run(() => DoMultiplication(3,6))
};

All this code does is start all of the tasks at the same time and collect their references in an array named new[].

The Task class also provides some static helper methods to allow developers to wait until all of the tasks are completed; the static helper methods of the Task class are list below:

Task.WaitAll(tasks);
await Task.WhenAll(tasks);

Programmer can use the following pair of methods in cases where you only want one method to complete before continuing execution:

Task.WaitAny(backgroundTasks);
await Task.WhenAny(backgroundTasks);

Since some of the tasks can run for a while, you might want to cancel them before their execution completes. In that case, you can trigger the cancellation with the following C# code example:

var tokenSource = new CancellationTokenSource();
var cancellableTask = Task.Run(() =>
{
    // do long-running processing   

}, tokenSource.Token);

// Cancellation of the task

tokenSource.Cancel();
try
{
    await cancellableTask;
}
catch (OperationCanceledException)
{
    // handle cancelation exception
}

C# Asynchronous Methods for I/O operations

Since the release of .NET 4.0, Asynchronous methods have been added to the existing classes for input/output and I/O-related operations. For example, the FileStream class provides the following methods for performing operations Asynchronously in C#:

using (FileStream src = new FileStream(srcFile, FileMode.Open),
                  dest = new FileStream(destFile, FileMode.Create))
{
    await src.CopyToAsync(dest);
}

Here is another example code example of how to use the FileStream class in C#:

using (var http = new HttpClient())
{
    var data = await http.GetStringAsync(url);
}

The above code example is of the HttpClient class, which is primarily used for performing HTTP network operations. As you can see, the class provides helpful methods for Asynchronous data operations. In the above code example, we have used one of its async methods: GetStringAsync.

What is the Target Environment for Asynchronous Execution in C#?

How do you determine where the Asynchronous execution is going to occur when implementing TAP? You can implement it in any number of potential contexts. You may run it on the UI thread, or use a thread pool for Asynchronous I/O operation. A TAP method can even have nothing to execute, and in that case, it would simply return a Task.

The caller method of the TAP method could block, waiting for the TAP method to complete the execution by synchronously waiting on the dependent task, or, it could create continuation code upon the Asynchronous operation completion. The creator of this additional continuation code would have control over where they want the code to execute. This can be achieved implicitly using language features such as await in C# or through the Task class explicitly.

Read: Handling Exceptions in Asynchronous Methods in C#

Final Thoughts on Asynchronous Programming Patterns in C# and .NET

In this programming tutorial, we discussed, broadly, Asynchronous patterns in C# and .NET. Specifically, we focused on the Task-based Asynchronous Pattern (TAP) and previewed some example code and use cases for using it in our C# software development practices. We will be following up with future tutorials covering other Asynchronous patterns. Until then, check out some of our other C# software development guides and programming tips.

Tariq Siddiqui
Tariq Siddiqui
A graduate in MS Computer Applications and a Web Developer from India with diverse skills across multiple Web development technologies. Enjoys writing about any tech topic, including programming, algorithms and cloud computing. Traveling and playing video games are the hobbies that interest me most.

More by Author

Must Read