Search code examples
async-awaitevent-handlingblazorthread-safetyblazor-server-side

Calling async method in parent event handlers throws error


I have a child component in my page that manages some data editing. When I click SAVE in the child it raises an event that is handled in the parent. The parent handler then calls a method to get some data I need in the parent. Calling that method inside the handler is where it fails. Here is where the event is raised in the child

        private async void SaveEditChange(EditContext editContext)
        {
            <<does some stuff to get the return object ready>>

            await SaveEditRequestEvent.InvokeAsync(Request);
        }

Here is the parent handler.

       protected async void SaveEditRequestEvent(RequestDTO editedRequest)
        {

            var request =  await RequestDomain.GetRequestAsync(editedRequest.RequestId).ConfigureAwait(false);

            <<do some stuff with the request object>>

            NavManager.NavigateTo("/");
        }

The call to RequestDomain.GetRequestAsync(editedRequest.RequestId).ConfigureAwait(false); is the first thing that happens in the handler. That method returns an object type. When it tries to execute that method it fails back to the child where the event was raised

enter image description here

Most of the articles I've read say to enclose the method call in a lambda call like `InvokeAsync(()=> RequestDomain.GetRequestAsync(editedRequest.RequestId).ConfigureAwait(false)). Then I get an error that it can convert an "Action" to the object type I'm returning.

I think this has to do with maintaining thread safety but I'm not certain and I'm getting a headache from it.


Solution

  • The direct error comes from using .ConfigureAwait(false).

    That is a sensible optimization in services but it should not be used in toplevel UI code. Be it WinForms, MAUI or Blazor.

    With ConfigureAwait(false) you are actually saying you don't care on which Thread the code resumes, but as the erorr shows that does matter.

    Furthermore you have two async void methods here. That will cause other problems, don't do that. All Blazor lifecycle and UI events can return either plain void or async Task .