【问题标题】:Static property in asp.net core middleware is shared between requests?asp.net核心中间件中的静态属性在请求之间共享?
【发布时间】:2018-03-11 10:40:31
【问题描述】:

我有一个静态类 User 和一个静态属性 Username。我在每个 url 请求的中间件中设置了这个属性。然后我在站点的标题中向用户显示Username

在每次请求时,都会设置此静态属性,然后将其显示在视图中。我假设每个请求在属性中都有自己的(正确的)值,并且该值不会在不同的请求之间共享?

那么,如果请求 1 的值为 adam 而请求 2 的值为 john,adam 会在 header 中看到 adam 而 john 会看到 john?这在我的应用中运行良好,但只是想确保它在概念上是正确的?

【问题讨论】:

  • 对象的静态属性在不同请求之间共享,至少只要您在单个实例/单个计算机上运行。但是,您可能会考虑为您的用例缓存而不是使用静态属性:official docs。您必须有一个键或一个差异化符,否则所有请求都会看到相同的值。
  • 谢谢乔治。我知道静态属性是共享的,但是如果静态属性在每个请求中具有不同的值。请求之间的值是否会重叠(在单台计算机上)?
  • 你应该假设请求是并行运行的,所以使用静态属性你可以有以下情况: Req1 设置值adam -> Req2 设置值john -> Req1 打印值john -> Req2 打印值johnHere's the official docs about sessions data and caching。简而言之,值可能会重叠(然后主要是在生产中,您的负载可能比调试时更高)
  • 不,它在概念上根本不正确。静态不是线程安全的。每个请求都在单独的线程中运行,并且可以单独修改影响所有其他线程(以及请求)的静态。在任何多线程环境中,您都应该避免像瘟疫一样的静态问题,其中 Web 服务器就是一个主要示例。

标签: asp.net-core asp.net-core-middleware


【解决方案1】:

正如您已经获悉的那样,这是HttpContext.Items 的一个很好的候选对象,具有唯一的对象键以避免键冲突。由于每个上下文对于每个请求都是唯一的,因此它们将允许值不会在不同请求之间共享。您不是在中间件上将值设置为静态值,而是在当前请求上下文中。

public class SampleMiddleware {
    public static readonly object SampleKey = new Object();

    public async Task Invoke(HttpContext httpContext) {
        httpContext.Items[SampleKey] = "some value";
        // additional code omitted
    }
}

其他代码可以使用存储在HttpContext.Items中的值 中间件类暴露的key:

public class HomeController : Controller {
    public IActionResult Index() {
        string value = HttpContext.Items[SampleMiddleware.SampleKey];
    }
}

参考Introduction to session and application state in ASP.NET Core

所以只有键是静态的,但项目中设置的值对于每个请求都是唯一的。这意味着在您的情况下,如果请求 1 的值 adam 并且请求 2 的值 john,则 adam 将在标题中看到 adam 而 john 将在标题中看到 john

【讨论】:

    猜你喜欢
    • 2015-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    相关资源
    最近更新 更多