我在这样的 Web 服务方法中使用 Cache
:
var pblDataList = (List<blabla>)HttpContext.Current.Cache.Get("pblDataList");
if (pblDataList == null)
{
var PBLData = dc.ExecuteQuery<blabla>(@"SELECT blabla");
pblDataList = PBLData.ToList();
HttpContext.Current.Cache.Add("pblDataList", pblDataList, null,
DateTime.Now.Add(new TimeSpan(0, 0, 15)),
Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
}
但我想知道,这段代码是线程安全的吗? Web 服务方法被多个请求者调用。当缓存为空时,多个请求者可能会同时尝试检索数据并添加到 Cache
。
查询需要 5 到 8 秒。围绕这段代码引入一个 lock 语句会防止任何可能的冲突吗? (我知道可以同时运行多个查询,但我想确保一次只运行一个查询。)
最佳答案
缓存对象是线程安全的但HttpContext.Current
将无法从后台线程获得。这可能适用于您,也可能不适用于您,从您的代码片段,无论您实际上是否正在使用后台线程,但如果您现在正在使用或决定在将来的某个时候使用,则应牢记这一点。
如果有任何机会你需要从后台线程访问缓存,那么使用HttpRuntime.Cache相反。
此外,虽然缓存上的单个操作是线程安全的,但顺序查找/存储操作显然不是原子的。您是否需要它们是原子的取决于您的特定应用程序。如果同一个查询运行多次可能是一个严重的问题,即如果它会产生比您的数据库能够处理的更多的负载,或者如果返回数据的请求立即被覆盖在缓存,那么您可能希望在整个代码块周围放置一个锁。
但是,在大多数情况下,您确实希望先进行概要分析,看看这是否真的是个问题。大多数 Web 应用程序/服务并不关心缓存的这一方面,因为它们是无状态的,缓存是否被覆盖无关紧要。
关于c# - 安全使用 'HttpContext.Current.Cache',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2638345/