据我所知,AspNetCore没有 https://blog.stephencleary.com/2017/03/aspnetcore-synchronization-context.html 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"));
}
出乎我的意料 ,res
的值为4
。我很惊讶,因为我相信SetData
是同步上下文的一部分。 (这不应该存在于asp.net core中)
更多,当我使用ConfigureAwait(false)
, 我有null
in res
.
所以现在我很困惑。因为ConfigureAwait
不应该对 ASP.NET Core 产生影响 https://stackoverflow.com/questions/42053135/configureawaitfalse-relevant-in-asp-net-core
问题:
如果asp.net core没有SynchronizationContext,那为什么呢?4
之后可用await
?为什么ConfigureAwait
在非 SynchronizationContext 环境中更改结果?
我很惊讶,因为我相信 SetData 是同步上下文的一部分。 (这不应该存在于asp.net core中)
No; SetData
是线程本地存储(TLS)。所以它与特定的线程相关联。这与同步上下文没有任何关系。
更多,当我使用ConfigureAwait(false)时,我在res中得到null。
根据您运行此代码的时间、服务器的繁忙程度等,您可能会得到null
or 4
有还是没有ConfigureAwait(false)
.
如果asp.net core没有SynchronizationContext,那么为什么await之后4可用?
这是一个特定于线程的值。没有SynchronizationContext
在 ASP.NET Core 上,您的代码将在任何可用的线程池线程上恢复。如果那个线程happens如果是启动该方法的同一个线程,那么 TLS 将仍然存在,因为它是针对该特定线程的。
同样的行为实际上也适用于 ASP.NET pre-Core。在这种情况下,有一个SynchronizationContext
,但该上下文不依赖于任何特定线程。就像 ASP.NET Core 一样,ASP.NET Core 之前版本上的异步方法可以在任何可用的线程池线程上恢复,因此 TLS 数据在某个时间之后可能存在,也可能不存在。await
.
为了用数据支持这个理论,尝试记录Environment.CurrentManagedThreadId
之前和之后await
并查看当前数据与保持不变的 id 之间是否存在任何相关性。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)