2012-04-22 16 views
6

Klasa Application w asp.net ma mechanizm Lock do obsługi bezpieczeństwa wątków.Aplikacja a pamięć podręczna: mechanizm blokowania

Jak wiemy - dostęp do Application można uzyskać globalnie.

próbki:

Application.Lock(); 
Application["MyCode"] = 21; 
Application.UnLock(); 

ok.

ale

Również Cache jest ogólnie dostępne (i robi się mechanizm zamka, a także stosowany do usuwania/dodawania elementów)

więc dlaczego Application posiada mechanizm blokady i Cache nie?

Odpowiedz

6

Application to datastore pozostające ze starej technologii ASP. Ma jedną globalną blokadę. Po wywołaniu Application.Lock() wszystkie dostępy do obiektu aplikacji we wszystkich wątkach są blokowane.

Z drugiej strony nowszy obiekt Cache, który został wprowadzony za pomocą programu ASP.NET, umożliwia korzystanie z własnej semantyki blokowania. Możesz użyć instrukcji .NET w wersji lock, aby zapewnić bezpieczny dostęp do obiektu pamięci podręcznej z zachowaniem wątków, przy jednoczesnym zachowaniu możliwie największej równoległości aplikacji internetowej. Instrukcja lock jest znacznie bezpieczniejsza, ponieważ blokada jest gwarantowana do zwolnienia po zamknięciu bloku lock. Obiekt aplikacji tego nie gwarantuje. Pamięć podręczna zapewnia także mechanizmy automatycznego wygaśnięcia, które są bardziej odpowiednie dla, cóż, pamięci podręcznej. Może również wygasać klucze na podstawie umów o zależności i opcjonalnych priorytetów, których oczywiście obiekt aplikacji nie ma.

Nie widzę powodu, aby używać obiektu Application przez obiekt Cache.

Przykład: Załóżmy, że masz sto przedmiotów w pamięci podręcznej i masz pojedynczy przedmiot, który chcesz przechowywać w pamięci podręcznej, jeśli jeszcze tam nie jest. Podczas korzystania Application, to zrobić:

if(Application["someData"] == null) 
{ 
    Application.Lock(); 
    if(Application["someData"] == null) 
    { 
     Application["someData"] = getValue(); //a very long time consuming function 
    } 
    Application.Unlock(); 
} 

W tym scenariuszu wszystko ma dostęp do obiektu Application są blokowane nawet jeśli są całkowicie nieistotne. A w przypadku, gdy getValue() powoduje wyjątek, Twoja Aplikacja zostanie zawieszona, ponieważ blokada nie zostanie zwolniona. Musisz owinąć wokół niego obiekt try .. finally, aby upewnić się, że jest bezpieczny.

Z drugiej strony w przypadku korzystania z Cache obiekt, należy to zrobić:

if(Cache["someData"] == null) 
{ 
    lock(myLockObject) // or other shared lock for that single value 
    { 
     if(Cache["someData"] == null) 
     { 
      Cache["someData"] = getValue(); 
     } 
    } 
} 

W tym przypadku tylko bloki kodu, które wymagają dostępu do myLockObject będzie czekał. Inne, które mają dostęp do Cache, będą działały równolegle. A w przypadku, gdy getValue() zgłasza wyjątek, twoja blokada zostaje zwolniona bez żadnych problemów pozwalających na kontynuowanie wykonywania innych wątków.

+1

Kolekcja pamięci podręcznej została wykonana w sposób bezpieczny dla wątków przez firmę Microsoft. Nie jest wymagane zewnętrzne blokowanie. –

+3

Cache sama w sobie jest bezpieczna dla wątków, gwarantuje jedynie niepodzielność atomowości. Spójrz na przykładowy kod powyżej. Jeśli nie masz instrukcji 'lock', wiele wątków będzie wywoływać' getValue() 'w tym samym czasie, niezależnie od tego, czy pamięć podręczna jest bezpieczna dla wątków czy nie. –

+0

I zastanawiam się, dlaczego tak się stało, mówiąc: "ta odpowiedź nie jest użyteczna". Naprawdę? –

Powiązane problemy