Code Tip: How to work with asynchronous event handlers in C#?

Have you ever faced a need to raise an event in C#? I am almost certain the answer is “Yes, and I had no problems with it“. So did I, but as usual, there are cases when raising an event can be tricky.

All code snippets from .NET source code in this post refer to .NET 5 release branch on GitHub. However, everything demonstrated in this post can be used in .NET Framework, .NET Core and .NET 5.

Author’s note

Imagine a Demo class with a single DemoEvent event and a Raise method:

public class Demo
{
  public event EventHandler DemoEvent;

  public void Raise()
  {
    this.DemoEvent?.Invoke(this, EventArgs.Empty);
    Console.WriteLine("All handlers have been executed!");
  }
}

Inside Program.Main, create a new instance of the Demo class and subscribe for the DemoEvent event:

class Program
{
  static void Main(string[] args)
  {
    var instance = new Demo();
    instance.DemoEvent += (
      sender,
      eventArgs) =>
    {
      Console.WriteLine("Executed!");
    };
    instance.Raise();
  }
}

Running the code prints the following:

Executed!
All handlers have been executed!

Everything seems all right by now. So, let’s make this situation a bit more complicated and replace synchronous event handler with an asynchronous one:

// class: Program / Main()
//...
instance.DemoEvent += async (
  sender,
  eventArgs) =>
{
  await Task.Delay(10);
  Console.WriteLine("Executed!");
};
//...

This new, asynchronous version prints the following:

All handlers have been executed! 

This isn’t what we expected.

(At this moment, on the reader’s side)

Oh no! One more post about async-await and event handlers! I am out!

Disappointed reader

(Sound of clapping browser page)

Hey, await! I promise, I won’t say anything about when or how you should or shouldn’t use async-await! The post is about the opposite. Here, I want to share a way of how you can improve Demo class to extend support for both synchronous and asynchronous event handlers.

(Sound of incoming HTTP GET)

Don’t want to read theory and want to see the code? The complete sample (with all the improvements) is available as Gist.

Want to know more? Let’s dig into.

Continue reading “Code Tip: How to work with asynchronous event handlers in C#?”

Code Tip: How to invoke C# delegate with arguments from dependency injection container?


UPDATE 08.27.2018


The previous version of post had several issues:

  • The first issue was related to handling of dynamically generated delegates (the usage of DynamicMethod wasn’t considered).
  • The second issue was related to the pure async support in the InvokeDelegateAsync.

Both of these issues are fixed and the post is significantly updated (as well as gist).


The Problem

This time I would like share a solution to a problem I have faced recently – How do I invoke a C# delegate with arguments from dependency injection container?

Continue reading “Code Tip: How to invoke C# delegate with arguments from dependency injection container?”