Roy*_*mir 9 c# synchronizationcontext async-await asp.net-core
据我所知,AspNetCore没有 SynchronizationContext.
“重新进入”请求上下文涉及许多内务任务,例如设置 HttpContext.Current 和当前线程的身份和文化。
所以我创建了一个简单的 .Net Core Api 项目,并执行以下操作:
[HttpGet]
[Route("checkVar")]
public async Task<IActionResult> checkVar()
{
Thread.SetData(Thread.GetNamedDataSlot("Random"),4);
await Task.Delay(1000);
var res = Thread.GetData(Thread.GetNamedDataSlot("Random"));
}
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,res它的价值为4. 我很惊讶,因为我相信这SetData是同步上下文的一部分。(在asp.net core中不应该存在)
更多,当我使用时ConfigureAwait(false),我进入null了res。
所以现在我很困惑。因为ConfigureAwait 在asp.net core中不应该有影响
题:
如果 asp.net core 没有 SynchronizationContext,那么为什么在4之后可用await?为什么会ConfigureAwait在非 SynchronizationContext 环境中改变结果?
Ste*_*ary 13
我很惊讶,因为我相信 SetData 是同步上下文的一部分。(在asp.net core中不应该存在)
不; SetData是线程本地存储 (TLS)。所以它绑定到一个特定的线程。这与同步上下文没有任何关系。
更多,当我使用 ConfigureAwait(false) 时,我在 res 中得到了空值。
根据当您运行此代码,服务器的繁忙程度,等等,你可以得到null或4有或无ConfigureAwait(false)。
如果 asp.net core 没有 SynchronizationContext,那么为什么 4 在 await 之后可用?
这是一个线程特定的值。SynchronizationContextASP.NET Core上没有,您的代码将在任何可用的线程池线程上恢复。如果该线程恰好与启动该方法的线程相同,则 TLS 将仍然存在,因为它是针对该特定线程的。
相同的行为实际上适用于 ASP.NET pre-Core。在这种情况下,有一个SynchronizationContext,但该上下文不绑定到任何特定线程。就像 ASP.NET Core 一样,ASP.NET pre-Core 上的异步方法可以在任何可用的线程池线程上恢复,因此await.
为了用数据支持这一理论,请尝试Environment.CurrentManagedThreadId在 之前和之后进行日志记录await,看看存在的数据与保持不变的 id 之间是否存在任何相关性。
| 归档时间: |
|
| 查看次数: |
3747 次 |
| 最近记录: |