2009-04-16 26 views
20

W przeszłości zablokowałem dostęp do mechanizmu HttpRuntime.Cache. Nie jestem pewien, czy naprawdę zbadałem problem w przeszłości, a ślepiec otoczył go zamkiem.Najlepsze praktyki HttpRuntime.Cache

Czy uważasz, że to naprawdę konieczne?

+0

http://stackoverflow.com/questions/447705/locking-httpruntime-cache-for-lazy-loading wydaje się, że pamięć podręczna jest bezpieczna dla wątków –

+0

język/platforma? – Javier

Odpowiedz

2

Nie sądzę, że konieczne jest zawijanie dostępu do właściwości HttpRuntime.Cache za pomocą blokady, ponieważ właściwość .Cache jest statyczna, a ponadto wątkowo bezpieczna.

Istnieje wiele różnych sposobów uzyskania dostępu do obiektu pamięci podręcznej (HttpRuntime.Cache, HttpContext.Current.Cache, PageCache itp.). Wszystkie uzyskują dostęp do tego samego obiektu pamięci podręcznej, ponieważ w danej domenie aplikacji istnieje tylko jeden obiekt pamięci podręcznej, ponieważ jest to efektywnie bezpieczny dla wątków obiekt Singleton.

10

Ten artykuł sugeruje, zamek powinien być stosowany:

http://msdn.microsoft.com/en-us/magazine/cc500561.aspx

Cytat:

Problemem jest to, że jeśli masz zapytanie, które trwa 30 sekund i jesteś Wykonanie strony co sekundę, w czas potrzebny na zapełnienie pozycji pamięci podręcznej , 29 innych żądań pojawi się , z których wszystkie spróbują do zapełnij element pamięci podręcznej własnymi, zapytaniami do bazy danych. Aby rozwiązać ten problem , można dodać blokadę wątku do zatrzymać wykonywanie innych stron od , prosząc o dane z bazy danych.

Oto ich fragment kodu:

// check for cached results 
object cachedResults = ctx.Cache["PersonList"]; 
ArrayList results = new ArrayList(); 

if (cachedResults == null) 
{ 
    // lock this section of the code 
    // while we populate the list 
    lock(lockObject) 
    { 
    cachedResults = ctx.Cache["PersonList"]; 
    // only populate if list was not populated by 
    // another thread while this thread was waiting 
    if (cachedResults == null) 
    { 
     cachedResults = ... 
     ctx.Cache["PersonList"] = cachedResults; 
    } 
    } 
} 

Nie testowałem tego kodu, ale byłbym bardzo zainteresowany, aby usłyszeć kogoś, kto dokonał oceny tego podejścia w środowisku produkcyjnym.

+11

Nie sądzę, że jest to konieczne z punktu widzenia buforowania bezpieczeństwa wątków - bardziej polega to na zapobieganiu wielokrotnym dostępom do bazy danych w celu przeprowadzenia potencjalnie kosztownej kwerendy. – zcrar70

+1

Zgadzam się z tobą. – frankadelic

+5

Tylko niewielka, ale ważna kwestia w przykładzie: między blokadą (lockObject) a if (cachedResults == null), buforowany element powinien zostać ponownie pobrany. Zobacz ten http: // stackoverflow.com/questions/39112/what-is-the-best-way-to-lock-cache-in-asp-net dla właściwego przykładu. –

2

Nie sądzę, że blokowanie jest odpowiedzią na poniższy problem, szczególnie w środowisku produkcyjnym, w którym jest kilka serwerów z uruchomioną aplikacją.

Problem polega na tym, że jeśli masz zapytanie, które trwa 30 sekund, a strona jest uruchamiana co sekundę, w czasie, w którym zapełni się element pamięci podręcznej, pojawi się 29 innych żądań, z których wszystkie będą spróbuje zapełnić element pamięci podręcznej własnymi zapytaniami do bazy danych. Aby rozwiązać ten problem, możesz dodać blokadę wątków, aby zatrzymać wykonywanie innych stron żądań danych z bazy danych.