发布于 2020-04-26 06:39:15
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(),这将在线程池线程上抛出异常,因为没有同步上下文。
发布于 2020-04-23 01:30:21
async void方法在启动或完成时通知它们的同步上下文,任何从异步空方法抛出的异常都直接引发到同步上下文。
这些方法从不通知同步上下文。相反,如果存在同步上下文,则可以将它们调度为在同步上下文中运行。
如果任务继续执行时没有设置同步上下文,则使用的是和TaskScheduler。
在ASP.NET核心中,此同步上下文被删除
是的,这个同步上下文指的是AspNetSynchronizationContext中的ASP.NET (非核心),它负责输入HTTP请求的上下文,这样就可以在异步方法中使用特定于请求的数据。设置了HttpContext.Current。
这些数据在ASP.NET核心中的处理方式已经改变了,因此不再需要保留这样有问题的同步上下文。
删除此同步上下文并不意味着从.NET核心中删除同步上下文。
https://stackoverflow.com/questions/61225603
复制相似问题