首页 > 解决方案 > ASP.NET Core 应用程序中的异步 void 方法如何报告进度

问题描述

在 .NET Framework 中,async void方法在启动或完成时通知其同步上下文,并且从方法抛出的任何异常async void都直接引发到同步上下文。在 ASP.NET Core 中,此同步上下文已被删除

那么,async void由于同步上下文不再存在,方法在哪里报告它开始、完成以及是否在 ASP.NET Core 应用程序中发生任何异常?

标签: c#asp.net-coreasync-await

解决方案


TLDR:没有同步上下文,这意味着上下文不知道操作的开始和结束。在线程池线程上抛出异常。

编译器将async void转换方法。以此为例

public async void Test() 
{
}

生成的代码看起来像这样

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);
}

这里的重要部分是AsyncVoidMethodBuilder struct. 查看该Create()函数,您可以看到它尝试查找当前的SynchronizationContext,如果有,则调用virtual OperationStarted(). 由于 .net 核心没有同步上下文,这将被跳过。

这个构建器的下一个有趣的部分是AwaitUnsafeOnCompleted(). 这是在您的方法内部调用的函数,您有一个await. 如果那里出现异常,ThrowAsync()就会发生,这将在线程池线程上引发异常,因为没有同步上下文。


推荐阅读