我们使用以下模式来处理我们的 asp.net 应用程序的通用对象缓存。
private object SystemConfigurationCacheLock = new object();
public SystemConfiguration SystemConfiguration
{
get
{
if (HttpContext.Current.Cache["SystemConfiguration"] == null)
lock (SystemConfigurationCacheLock)
{
if (HttpContext.Current.Cache["SystemConfiguration"] == null)
HttpContext.Current.Cache.Insert("SystemConfiguration", GetSystemConfiguration(), null, DateTime.Now.AddMinutes(1), Cache.NoSlidingExpiration, new CacheItemUpdateCallback(SystemConfigurationCacheItemUpdateCallback));
}
return HttpContext.Current.Cache["SystemConfiguration"] as SystemConfiguration;
}
}
private void SystemConfigurationCacheItemUpdateCallback(string key, CacheItemUpdateReason reason, out object expensiveObject, out CacheDependency dependency, out DateTime absoluteExpiration, out TimeSpan slidingExpiration)
{
dependency = null;
absoluteExpiration = DateTime.Now.AddMinutes(1);
slidingExpiration = Cache.NoSlidingExpiration;
expensiveObject = GetSystemConfiguration();
}
private SystemConfiguration GetSystemConfiguration()
{
//Load system configuration
}
问题是,在负载下(约 100,000 个用户),我们看到 TTFB 出现巨大跳跃,因为 CacheItemUpdateCallback 会阻止所有其他线程执行,直到它完成从数据库刷新缓存。
所以我想我们需要的是当第一个线程在缓存过期后试图访问它时,一个异步线程被触发以更新缓存但仍然允许所有其他执行线程从旧缓存中读取的解决方案直到更新成功。
.NET Framework 中是否内置了任何可以 native 处理我所要求的内容,或者我必须从头开始编写它?请你的想法...
一些事情...
HttpContext.Current.Cache 的使用是偶然的,不一定是必需的,因为我们在单例上使用私有(private)成员来保存缓存数据没有问题。
请不要评论缓存时间、SPROC 效率、我们为什么首先缓存等等,因为它不相关。谢谢!
最佳答案
AppFabric 可能非常适合您的需求。
关于c# - 如何实现异步缓存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8279760/