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?
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?
Zgodnie z tą dokumentacją http://msdn.microsoft.com/en-us/library/system.web.caching.cache(VS.80).aspx dostęp do obiektu pamięci podręcznej jest bezpieczny dla wątków. Jeśli chodzi o obiekty przechowywane w pamięci podręcznej, bezpieczeństwo musi pochodzić z innego miejsca.
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.
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.
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
Zgadzam się z tobą. – frankadelic
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. –
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.
http://stackoverflow.com/questions/447705/locking-httpruntime-cache-for-lazy-loading wydaje się, że pamięć podręczna jest bezpieczna dla wątków –
język/platforma? – Javier