c# - 使用 LegacyAspNetSynchronizationContext 对 .net 4.7 中的异步/等待代码有什么影响?

标签 c# asp.net webforms async-await .net-4.7

我正在将遗留的 Asp.Net WebForms 项目升级到 .net 4.7。

在我的配置中,我将目标框架设置为 4.7 并将同步上下文设置为使用新的 AspNetSynchronizationContext(尽管我相信如果省略后者则隐含)以允许新的 async/await 工作方法,例如

<httpRuntime targetFramework="4.7" />
...
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />

但后来我发现很多代码如下:

var myTask = DoSomethingAsync();
return myTask.Result;

没有等待任务的结果导致应用程序挂起。

如果我更改配置以使用 LegacyAspNetSynchronizationContext ...

<add key="aspnet:UseTaskFriendlySynchronizationContext" value="false" />

...遗留的非等待代码再次运行,新的async/await 方法出现 运行。我在 this MSDN article 中读到时说“出现”那:

the behavior of async / await is undefined in ASP.NET unless this switch has been set

为什么它是未定义的?这是否意味着该行为不可预测或根本行不通?

如果我有如下代码片段,当它在 LegacyAspNetSynchronizationContext 中调用时会或可能发生什么?

public async Task<bool> DoSomethingElseAsync()
{
    return await CallSomeApiAsync().ConfigureAwait(false);
}

最佳答案

使用 LegacyAspNetSynchronizationContext意味着您在使用任务时没有得到定义的行为;遗留的同步模型不是为与任务调度一起工作而构建的。如果您想在 ASP.NET 中使用任务,您必须使用新的同步上下文。

var myTask = DoSomethingAsync();
return myTask.Result;

此代码块位于 Task 上.打电话Wait()Result正在运行Task将阻塞调用线程直到 Task完成。

除非您知道,否则您无法安全地阻止任务:

  • 任务已经完成(在这种情况下您并不是真正的阻塞)。
  • 同步上下文不会尝试在启动任务的同一线程上恢复。

唯一合理的解决方案是一直使用任务。任何试图阻止 Task 的方法应该改成返回 TaskTask<TResult>await运行 Task相反。

关于c# - 使用 LegacyAspNetSynchronizationContext 对 .net 4.7 中的异步/等待代码有什么影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48808923/

相关文章:

c# - RDLC 报告未在 IE 11 中显示

C#,创建 .txt 文件

javascript - 在 JavaScript 中获取 ASP.NET 标签的文本或值

html - 从在 asp.net 中使用 css3 设置样式的 html 复选框获取值/状态

c# - 使用 Ninject 的项目依赖项

c# - 当需要该类 WPF 的多个实例时,模型内部的 INotifyPropertyChanged

c# - 获取占位符中动态生成的文本框的值

javascript - 将 Razor 列表传递给 Javascript (JSON)

asp.net 使用管理员帐户运行程序

c# - 如何在 WebForms 中不刷新页面的情况下在服务器上触发事件