2011-11-26 14 views
6

Korzystamy z następującego wzoru do obsługi buforowania uniwersalnych obiektów dla naszej aplikacji asp.net.Jak zaimplementować buforowanie asynchroniczne?

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 
} 

Problem polega na tym, że gdy pod obciążeniem (~ 100.000 użytkowników) widzimy ogromny skok w TTFB jako bloki CacheItemUpdateCallback wszystkie inne wątki z wykonaniem dopóki nie zakończy odświeżyć pamięć podręczną z bazy danych.

Potrzebowałem rozwiązania polegającego na tym, że gdy pierwszy wątek po wygaśnięciu pamięci podręcznej próbuje uzyskać do niego dostęp, uruchamiany jest asynchroniczny wątek w celu aktualizacji pamięci podręcznej, ale nadal pozwala na odczyt wszystkich pozostałych wątków wykonawczych ze starego pamięć podręczną, dopóki nie zostanie pomyślnie zaktualizowana.

Czy jest coś wbudowanego w platformę .NET, które może natywnie obsługiwać to, o co pytam, czy będę musiała napisać to od nowa? Twoje myśli proszę ...

Kilka rzeczy ...

Zastosowanie HttpContext.Current.Cache jest przypadkowe, a niekoniecznie istotne jak mamy żadnego problemu przy użyciu członków prywatnych na Singleton do przechowuj dane z pamięci podręcznej.

Proszę nie komentować czasów pamięci podręcznej, wydajności SPROC, dlaczego buforujemy w pierwszej kolejności itp., Ponieważ nie jest to istotne. Dzięki!

Odpowiedz

0

Więc okazuje się po kilku godzinach śledztwa, że ​​problem nie blokuje innych wątków, jak początkowo myślałem że CacheItemUpdateCallback, w rzeczywistości to nie dokładnie to, co chciałem się asynchronicznie, ale był to śmieciarz, który zatrzymał wszystko, by oczyścić LOH.

+0

A rozwiązaniem było? – orjan

+0

Nie używać tego wzoru do przechowywania obiektów, które mogłyby następnie trafić do LOH. –