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.
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. –
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. –
I zastanawiam się, dlaczego tak się stało, mówiąc: "ta odpowiedź nie jest użyteczna". Naprawdę? –