【问题标题】:Is HttpContextAccessor Thread Safe?HttpContextAccessor 线程安全吗?
【发布时间】:2018-10-29 14:49:16
【问题描述】:

一般有两种方式可以访问用户的HttpContext,通过:

  • 为服务注入的 IHttpContextAccessor(和 HttpContextAccessor)如下:httpContextAccessor.HttpContext
  • 或通过控制器的属性如下:this.HttpContext

在我的代码库中,我们使用了这两种情况。对于HttpContextAccessor 的使用,我们将它们主要用于为每个请求共享的公共单例服务(例如日志记录、会话处理等)。我认为这应该是线程安全的,因为HttpContextAccessor 应该知道如何处理它,但我看到这条推文让我感到厌烦:https://twitter.com/davidfowl/status/907248318538903553

到目前为止看起来还不错,但是是否有任何确认它是线程安全的?

【问题讨论】:

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


    【解决方案1】:

    您混淆了两个不同的概念。线程安全仅与 HTTP 请求相关,因为 HTTP 请求需要使用线程。不过,差不多就是这样。 HttpContext 是请求范围的,因此在单个请求的上下文中,假设您只停留在一个线程上或所有操作线程都在该特定请求的上下文中运行,您将不会发生溢出。

    当您开始启动在后台运行的线程时,即在请求管道之外,事情变得不稳定。在这种情况下,HttpContext 可能存在也可能不存在,或者后台线程可能与原始线程不同。这就是线程不安全的来源。

    不管HttpContext 是否是线程安全的,这是一个错误的问题。相反,您需要询问在什么上下文中线程上正在执行什么工作。如果您在请求管道中,那么HttpContext 将实际上是线程安全的,但这需要捕获您触发的所有线程,这几乎否定了使用多个线程的有用性。您不妨只在原始线程上完成所有工作。处理 Web 请求与桌面或移动应用程序不同。在后者中,您需要保持主线程或 UI 线程空闲,因此必须分离线程。网络不是这样工作的。所有线程都是瞬态的,服务于特定的请求,然后返回到池中。

    【讨论】:

    • 这就是我的假设,因为每个请求都是一个线程并且应该是自包含的。我们不会启动新线程来处理代码部分(除了使用异步,但这是另一回事)。唯一需要担心的是,当我有两个线程使用相同的公共服务时,该服务尝试同时通过HttpContextAccessor.HttpContext 访问两个线程的 HttpContext。
    • 只要你在你的服务中注入HttpContextAccessor——服务是否是单例的——你会没事的。
    • 这不一定是真的。 HttpContext 可以为 null,如果上下文不在请求管道中,则为 null。
    猜你喜欢
    • 2020-04-15
    • 2011-07-04
    • 2014-04-26
    • 2012-11-30
    • 2010-12-30
    • 2013-03-12
    • 2021-08-03
    • 2010-12-27
    • 2018-06-04
    相关资源
    最近更新 更多