Moving from Event-based asynchronous pattern (EAP) to Task-based asynchronous pattern (TAP) with cancellation


What’s the point of this blog post? In modern C#/.NET ecosystem there is encouragement to use async/await Task based asynchronous model over other asynchronous patterns and approaches. On the other side, there are still a lot of libraries (legacy, wrappers from other technologies/languages which uses events for callback calls, etc…) which use older EAP approach to execute asynchronous code.

Very often, I am faced with situation where I use modern TAP async approach, but I need to reference some libraries still using Event-Based async pattern. Furthermore, these EAP-based calls need to be finished when callbacks are returned or – in some cases – they need to be canceled after some deterministic period of time.

I was eager to document this and to share my findings. Just to refresh, I wrote very similar blog post here: https://www.jenx.si/2019/10/02/c-from-event-based-asynchronous-pattern-to-task-based-asynchronous-pattern/, but it can’t harm if I publish a little more raw version of EAP to TAP migration.

Let’s take a look what TAP and EAPs are.

The task-based asynchronous pattern (TAP) is one of the asynchronous programming pattern which is based on the System.Threading.Tasks.Task and System.Threading.Tasks.Task<TResult> types in the System.Threading.Tasks namespace, which are used to represent arbitrary asynchronous operations. TAP is the recommended asynchronous design pattern for new development. On short: if you are using async/await and Task entities then you are using TAP async pattern. For more information, please checkout this link: https://docs.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap

EAP stands for Event-based Asynchronous Pattern which is the event-based legacy model for providing asynchronous behavior. It requires a method that starts the processing and and one or more events, event handler delegate types to handle processing finished callbacks. EAP was introduced in the .NET Framework 2.0 and it’s no longer recommended for new development. For more information, see Event-based Asynchronous Pattern (EAP).

Let’s take a look at very simple EAP example. I will create simple trigger which uses EAP pattern for handling asynchronous programming.

EAP example

In this section I will show simple EAP example. I created MyAwesomeTrigger class which executes TriggerFired event after defined period of time.

I can use this trigger like this:

In Console, the output is as follows:

This is one of the “old practices” of asynchronous C# code execution. Thus, this kind of usage is not advised anymore in modern C# applications.

Modern C# code is using TAP (async/await, Task & Task<TResult> approach to asynchronous programming.

In the next section, I will briefly present simple TAP-based approach on asynchronous programming in C#.

TAP example

Below, analogues example as presented in previous chapter with Task-bsed async pattern.

I can use it as:

And my output is:

As said, TAP pattern is widely used in modern C# code.

I quickly presented both, EAP and TAP asynchronous code execution patterns. In the next section, I will present how to wrap/convert “old” EAP pattern into “modern” TAP based asynchronous pattern.


In the next section I will present one way how to wrap EAP example in TAP pattern with cancellation. Cancellation is very important, because in some cases your task can execute very long time, and you must be able to cancel asynchronous code execution if needed.

Next source code excerpt shows how to consume upper EAP-to-TAP code.

And, if I run the code I get expected results:


In this blog post I presented simple procedure/example how to convert C# EAP based async pattern to TAP-based one.

Asynchronous programming has never been easy, but with some good recipes and practices some task can be simplified and less error prone. I used similar approach as described in this blog post several times in my projects. So, if you find code in this blog post useful feel free to use it.

Happy coding.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.