gpt4 book ai didi

c# - ASP.NET Core 中 AsyncLocal 的安全性

转载 作者:IT王子 更新时间:2023-10-29 03:55:44 27 4
gpt4 key购买 nike

对于 .NET 核心, AsyncLocal CallContext 的替代品.但是,尚不清楚在 ASP.NET Core 中使用它有多“安全”。

在 ASP.NET 4 (MVC 5) 和更早版本中,thread-agility model of ASP.NET made CallContext unstable .因此,在 ASP.NET 中,实现每个请求逻辑上下文行为的唯一安全方法是使用 HttpContext.Current.Items。在幕后,HttpContext.Current.Items 是用 CallContext 实现的, 但它是以对 ASP.NET 安全的方式完成的。

相比之下,在 OWIN/Katana Web API 的上下文中,线程敏捷模型不是问题。在 careful considerations of how correctly to dispose it 之后,我能够安全地使用 CallContext .

但现在我正在处理 ASP.NET Core。我想使用以下中间件:

public class MultiTenancyMiddleware
{
private readonly RequestDelegate next;
static int random;

private static AsyncLocal<string> tenant = new AsyncLocal<string>();
//This is the new form of "CallContext".
public static AsyncLocal<string> Tenant
{
get { return tenant; }
private set { tenant = value; }
}

//This is the new verion of [ThreadStatic].
public static ThreadLocal<string> LocalTenant;

public MultiTenancyMiddleware(RequestDelegate next)
{
this.next = next;
}

public async Task Invoke(HttpContext context)
{
//Just some garbage test value...
Tenant.Value = context.Request.Path + random++;
await next.Invoke(context);

//using (LocalTenant = new AsyncLocal<string>()) {
// Tenant.Value = context.Request.Path + random++;
// await next.Invoke(context);
//}
}
}

到目前为止,上面的代码似乎工作得很好。但至少有一个危险信号。过去,确保 CallContext 至关重要被视为必须在每次调用后释放的资源。

现在我发现没有不言而喻的“清理”方法AsyncLocal .

我包含了代码,注释掉了,展示了如何 ThreadLocal<T>作品。是IDisposable ,所以它有一个明显的清理机制。相比之下,AsyncLocal不是 IDisposable .这令人不安。

这是因为 AsyncLocal尚未处于发布候选状态?还是真的不需要清理了?

即使 AsyncLocal在我上面的示例中使用得当,ASP.NET Core 中是否存在任何类型的老式“线程敏捷性”问题会使该中间件无法运行?

特别说明

对于那些不熟悉问题的人 CallContext在 ASP.NET 应用程序中,在 this SO post, Jon Skeet 中引用 in-depth discussion about the problem (反过来引用 commentary from Scott Hanselman )。这个“问题”不是错误 - 它只是一种必须仔细考虑的情况。

此外,我可以亲自证明这种不幸的行为。当我构建 ASP.NET 应用程序时,我通常将负载测试作为我的自动化测试基础结构的一部分。在负载测试期间,我可以见证 CallContext变得不稳定(可能有 2% 到 4% 的请求显示 CallContext 已损坏。我还看到 Web API GET 具有稳定的 CallContext 行为,但 POST 操作都不稳定的情况。唯一实现完全稳定的方法是依赖 HttpContext.Current.Items。

但是,在 ASP.NET Core 的情况下,我不能依赖 HttpContext.Items...没有这样的静态访问点。我还无法为我正在修改的 .NET Core 应用程序创建负载测试,这也是我自己没有回答这个问题的部分原因。 :)

Again: Please understand that the "instability" and "problem" I'm discussing is not a bug at all. CallContext is not somehow flawed. The issue is simply a consequence of the thread dispatch model employed by ASP.NET. The solution is simply to know the issue exists, and to code accordingly (e.g. use HttpContext.Current.Items instead of CallContext, when inside an ASP.NET app).

我提出这个问题的目的是了解这种动态如何在 ASP.NET Core 中应用(或不应用),这样我就不会在使用新的 AsyncLocal 时意外地构建不稳定的代码。构造。

最佳答案

我只是在查看 CoreClr 的 ExecutionContext 类的源代码: https://github.com/dotnet/coreclr/blob/775003a4c72f0acc37eab84628fcef541533ba4e/src/mscorlib/src/System/Threading/ExecutionContext.cs

根据我对代码的理解,异步本地值是每个 ExecutionContext 实例的字段/变量。它们不基于 ThreadLocal 或任何线程特定的持久化数据存储。

为了验证这一点,在我对线程池线程的测试中,当重复使用同一个线程池线程时,无法访问留在异步本地值中的实例,并且在下一次 GC 上调用了用于清理自身的“左”实例的析构函数循环,这意味着实例按预期进行了 GC。

关于c# - ASP.NET Core 中 AsyncLocal 的安全性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36511243/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com