C# 如何实现异步缓存?

C# 如何实现异步缓存?,c#,asp.net,C#,Asp.net,我们使用以下模式为asp.net应用程序处理通用对象的缓存 private object SystemConfigurationCacheLock = new object(); public SystemConfiguration SystemConfiguration { get { if (HttpContext.Current.Cache["SystemConfiguration"] == null) lock (SystemCon

我们使用以下模式为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
} 
问题是,当负载不足(约100000个用户)时,我们会看到TTFB中出现巨大的跳跃,因为CacheItemUpdateCallback会阻止所有其他线程执行,直到它完成从数据库刷新缓存为止

所以我认为我们需要的解决方案是,当缓存过期后的第一个线程尝试访问它时,一个异步线程被触发以更新缓存,但仍然允许所有其他执行线程从旧缓存读取,直到它成功更新为止

在.NET框架中是否有内置的东西可以本机处理我的请求,或者我必须从头开始编写它?请你想想

有几件事

HttpContext.Current.Cache的使用是偶然的,不一定是必需的,因为我们在单例上使用私有成员来保存缓存数据没有问题


请不要评论缓存时间、存储过程效率、我们为什么要首先缓存等等,因为这并不相关。谢谢

AppFabric可能非常适合您所寻找的产品


所以经过几个小时的调查,问题并不像我最初认为的那样是CacheItemUpdateCallback阻塞了其他线程,事实上,它确实异步地完成了我希望它做的事情,但是垃圾收集器停止了一切来清理LOH。

不要使用此模式来存储可能随后在LOH上结束的对象。