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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With