【问题标题】:Accessing data stored in HttpContext.Current.Items across threads跨线程访问存储在 HttpContext.Current.Items 中的数据
【发布时间】:2016-06-08 11:42:07
【问题描述】:

我目前正在开发一个调用外部服务并将一些数据缓存在 HttpContext.Current.Items 集合中以提高性能的系统。数据可以定期更改,并且它是用户敏感的,这就是为什么我们目前仅在当前 HttpRequest 期间存储它。

例子:

if (HttpContext.Current.Items[cacheKey] != null)
{
    LogHelper.Debug<ExampleService>("[- CACHED RESULT -] GetUser({0})", () => email);
    return (ExampleUser)HttpContext.Current.Items[cacheKey];
}

using (var client = new UserServiceClient())
{
    using (new OperationContextScope(client.InnerChannel))
    {
        LogHelper.Debug<ExampleService>("GetUser({0})", () => email);
        exampleUser = svc.GetUser(email);
        HttpContext.Current.Items.Add(cacheKey, exampleUser);
    }
}

在我的本地环境中,它的行为符合预期,并且主要在请求期间使用相同线程的暂存中也是如此,但是在生产中情况并非如此,并且仍然有多次调用相同的外部服务要求。从日志中可以看出,在线程ID与原始请求不匹配的情况下,HttpContext.Current.Items[cacheKey]中的值不会被返回。

我猜这意味着我目前对HttpContext.Current.Items 的理解是错误的,这不是适合我需要的解决方案。

因此,我的问题是,这是否可以在同一个请求中跨线程工作,如果可以,否则有什么合适的替代方案?

【问题讨论】:

  • HttpContext.Current 是每个线程的,因为您已经自己发现了。如果您想在其他线程中使用当前请求的 HttpContext.Current - 首先在当前线程中获取对它的引用,然后将其传递给另一个线程。
  • HttpContext.Current.Session 是一个专用于单个用户的区域;存储在 Session 中的任何对象将仅对创建它的用户/会话可用。
  • 我知道使用会话存储不是一个好主意,因为内存使用情况(这是可能存储的许多项目之一),而且如果站点稍后移动到负载均衡环境?

标签: c# caching model-view-controller httpcontext


【解决方案1】:

一种选择是使用 Session 来存储您的数据。不幸的是,它不适用于特定于 API 的请求(例如,移动设备调用服务器 API)。此外,服务器会话状态需要您的所有数据可序列化(数据库会话状态不需要)。

如果会话不满足您的要求,那么您应该转到下一个选项:使用受代表来自同一用户的请求(也称为访问令牌)的东西保护的缓存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多