【问题标题】:Is ASP.NET Core Session implementation thread safe?ASP.NET Core Session 实现线程安全吗?
【发布时间】:2019-10-10 18:30:18
【问题描述】:

我知道there is an analogous question 但那是关于 ASP.NET 而不是关于 ASP.NET Core。答案是 7 到 9 岁,在那里混合讨论 ASP.NET 和 ASP.NET Core 可能不是一个好主意。

在这种情况下我的意思是线程安全:

在属于同一会话的多个请求中使用Session(通过HttpContext 访问,通过注入的IHttpContextAccessor 访问)的读写方法(如Set(...))是否安全?

显而易见的答案是肯定的,因为如果它不安全,那么所有开发人员都应该让他们的会话访问代码线程安全......

我查看了DistributedSession source code,这似乎是默认设置(我在调试器中的会话是DistributedSession 的一个实例),并且没有任何序列化或其他技术(如锁)的痕迹。 ..即使是私人_store 成员也是纯粹的Dictionary...

这个线程对于并发修改使用如何是安全的?我错过了什么?

【问题讨论】:

    标签: multithreading session asp.net-core concurrency httpcontext


    【解决方案1】:

    DistributedSessionDistributedSessionStore 创建,即registered as a transient dependency。这意味着DistributedSessionStore 本身是隐式安全的,因为它实际上并没有在请求之间共享。

    会话使用字典作为基础数据源,该字典也是 DistributedSession 对象的本地数据源。当会话初始化时,会话在访问会话时通过反序列化缓存中存储的数据来懒惰地初始化_store 字典。 That looks like this:

    var data = _cache.Get(_sessionKey);
    if (data != null)
    {
        Deserialize(new MemoryStream(data));
    }
    

    所以这里对_cache的访问是一个单一的操作。 writing to the cache 时也是如此。

    至于IDistributedCache 实现,您通常可以期望它们是线程安全的以允许并行访问。例如MemoryCache 使用a concurrent collection as the backing store

    所有这一切对于并发请求的意义基本上是您不应该期望一个请求直接影响另一个请求的会话。会话通常只反序列化一次,因此在请求期间(由其他请求)发生的更新不会出现。

    【讨论】:

    • 非常感谢。同时我也做了一些研究。我是否理解正确,如果我按照我的描述访问会话,那么每个请求都会有一个非常独立的独占会话实例。同一会话中的并发请求不会干扰,它们的(零)价格不会立即看到彼此的写入。 该会话实例完成所有工作后,独占实例的私有存储字典的内容将写入公共存储。
    • 是的,每个请求都有自己的DistributedSession 实例,该实例在特定时间拥有自己的会话状态快照。只有在请求结束时才会提交会话,这会导致它被写回(共享)缓存。
    • 嘿,如果我从同一个浏览器发出并发请求,在共享缓存中使用相同的密钥数据,这将是一个问题,会话将是相同的,但会话状态的快照结果不同,如果我需要用新数据将相同的键写回缓存
    猜你喜欢
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-05
    • 2010-12-12
    • 2021-05-12
    • 1970-01-01
    相关资源
    最近更新 更多