【发布时间】: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