使用 LegacyAspNetSynchronizationContext 对 .net 4.7 中的异步/等待代码有什么影响?
What effect does using LegacyAspNetSynchronizationContext have with async / await code in .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
方法 出现 工作。我说 "appear" 正如我在 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
。在 运行 Task
上调用 Wait()
或 Result
将阻塞调用线程,直到 Task
完成。
你不能安全地阻止任务,除非你知道:
- 任务已经完成(在这种情况下你并没有真正阻止)。
- 同步上下文不会尝试在启动任务的同一线程上恢复。
唯一合理的解决方案是一直使用任务。任何试图阻塞 Task
的方法都应该改为 return a Task
或 Task<TResult>
and await
the 运行 Task
代替。
我正在将遗留 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
方法 出现 工作。我说 "appear" 正如我在 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
。在 运行 Task
上调用 Wait()
或 Result
将阻塞调用线程,直到 Task
完成。
你不能安全地阻止任务,除非你知道:
- 任务已经完成(在这种情况下你并没有真正阻止)。
- 同步上下文不会尝试在启动任务的同一线程上恢复。
唯一合理的解决方案是一直使用任务。任何试图阻塞 Task
的方法都应该改为 return a Task
或 Task<TResult>
and await
the 运行 Task
代替。