Reputation: 369
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
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
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