Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do async void methods report progress in ASP.NET Core applications

In .NET Framework, async void methods notified their synchronization context when they started or finished and any exception thrown out of an async void method was directly raised to the synchronization context. In ASP.NET Core, this synchronization context was removed.

So where does an async void method report that it started, finished, and if any exceptions occured in an ASP.NET Core application since the synchronization context no longer exists?

like image 210
PlebFred Avatar asked Dec 08 '22 10:12

PlebFred


1 Answers

TLDR: No sync context, meaning context is not informed of operation started and ended. Exceptions are thrown on threadpool thread.

An async void method will get transformed by the compiler. Take this as an example

public async void Test() 
{
}

Resulting generated code looks something like this

public void Test()
{
    <Test>d__0 stateMachine = new <Test>d__0();
    stateMachine.<>4__this = this;
    stateMachine.<>t__builder = AsyncVoidMethodBuilder.Create();
    stateMachine.<>1__state = -1;
    AsyncVoidMethodBuilder <>t__builder = stateMachine.<>t__builder;
    <>t__builder.Start(ref stateMachine);
}

Important part here is the AsyncVoidMethodBuilder struct. Looking at the Create() function, you can see that it tries to find the current SynchronizationContext, if there is one, then call the virtual OperationStarted(). Since there is not sync context for .net core, this will be skipped.

The next interesting part of this builder is the AwaitUnsafeOnCompleted(). This is the function that gets called when inside your method, you have an await. If an exception crops up in there, ThrowAsync() happens, which will throw an exception on a threadpool thread, as there is no sync context.

like image 154
JohanP Avatar answered Jun 04 '23 19:06

JohanP