2011-11-26 98 views
6

我們使用以下模式來處理我們的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 
} 

的問題是,當負載(〜10萬個用戶)下我們看到TTFB一個巨大的跳躍爲CacheItemUpdateCallback阻止執行,直到它已完成刷新從數據庫緩存中的所有其他線程。

所以我想我們需要的是解決方案,當緩存過期後的第一個線程嘗試訪問它時,異步線程被釋放以更新緩存但仍允許所有其他執行線程從舊緩存直到它成功更新。

.NET框架中是否有內置的東西可以本能地處理我所問的問題,還是我必須從頭開始編寫它?您的想法,請...

幾件事情......

使用該HttpContext.Current.Cache是​​偶然的,並不一定必要的,因爲我們已經有了使用私有成員在一個單沒有問題保存緩存的數據。

請不要評論緩存時間,SPROC效率,爲什麼我們緩存在第一位等,因爲它不相關。謝謝!

回答

0

因此,原來幾個小時的排查,這個問題是不是CacheItemUpdateCallback阻塞其他線程,因爲我本來以爲以後,實際上它也正是我想它異步但垃圾收集器阻止了一切清理LOH。

+0

解決方法是? – orjan

+0

不要使用此模式存儲可能隨後在LOH上結束的對象。 –