Search code examples
c#async-awaitblazorblazor-server-side

Why can an AsyncEventHandler method return void or Task?


Blazor has a callback AsyncEventHandler struct that is used for declaring events in a component. Here’s a useful discussion about how to get called by the event.

I’ve found that the method assigned to an AsyncEventHandler can return void or Task. How can it return void when it’s declared to return Task. Does the system view a return of void being a Task that has completed?

And I’m talking here of a method that returns void, not “async void”. So a truly synchronous method.


Solution

  • How can it return void when it’s declared to return Task.

    The delegate for an EventCallback is not explicitly declared to return a Task. Inside the EventCallback the method is stored in
    internal readonly MulticastDelegate? Delegate;

    A MulticastDelegate is for methods what an object reference is for class objects, it accepts all method signatures and return types.

    And later it is executed with type matching patterns:

    
    internal static Task InvokeAsync<T>(MulticastDelegate? @delegate, T arg)
    {
       switch (@delegate)
       {      
           case Action action:
               action.Invoke();           // void
               return Task.CompletedTask;
      
           case Func<Task> func:
               return func.Invoke();      // Task
    
           // more branches
       }
    }
    
    

    There are more branches, mostly for dealing with the optional T parameter. The relevant code is here.