PlebFred
PlebFred

Reputation: 369

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?

Upvotes: 4

Views: 699

Answers (2)

JohanP
JohanP

Reputation: 5472

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.

Upvotes: 8

weichch
weichch

Reputation: 10055

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

Those methods never notify synchronization context. Instead, they can be scheduled to run within synchronization context if there is one.

If there is no synchronization context set when the task continuation is resuming, TaskScheduler is used, and there is always a TaskScheduler.

In ASP.NET Core, this synchronization context was removed

Yes, this synchronization context refers to AspNetSynchronizationContext in ASP.NET (not Core), which is in charge of entering the context of an HTTP request, so that data specific to a request can be used in async methods. e.g. HttpContext.Current is set.

How those data handled in ASP.NET Core has been changed, so there is no need to keep such problematic synchronization context any more.

Removing this synchronization context does not mean synchronization context is removed from .NET Core.

Upvotes: 6

Related Questions