2013-03-26 3 views
1

В моем приложении asp.net я хочу кэшировать некоторые данные в HttpApplicationState.Является ли HttpApplicationState.RemoveAll() потоком безопасным?

Мой код, чтобы установить данные выглядит следующим образом:

Application.Lock(); 

Application.Set("Name", "Value"); 

Application.UnLock(); 

Когда я прочитал документацию, он говорит, что HttpApplicationState неявно поточно. Но во многих блогах написано, что мы должны использовать Application.Lock() и Application.Unlock() при записи данных на HttpApplicationState.

С другой стороны, я не смог найти документацию, в которой говорится, что мы должны использовать блокировку при чтении данных с HttpApplicationState или при ее очистке (используя метод Application.RemoveAll()).

Мои вопросы:

  1. Не должны ли мы позаботиться о безопасности потоков, когда мы называем RemoveAll? В моем приложении возможно, что один поток считывает данные с HttpApplicationState, тогда как другой поток может вызвать RemoveAll.
  2. В этом случае, если считывание и очистка HttpApplicationState возможно из двух разных потоков одновременно, следует ли читать слишком небезопасно?

ответ

2

Вам нужно только замок, если вы делаете более одной операции против состояния приложения. В вас случае, если вы просто делаете одну операцию, так что это совершенно безопасно без замка:

Application.Set("Name", "Value"); 

Если вы делаете более одной операции, и они полагаются друг на друга, вам нужен замок. Например:

Application.Lock(); 

string name = Application.Get("Name"); 

if (name == null) { 
    Application.Set("Name", "Value"); 
} 

Application.UnLock(); 
1

Насколько я могу судить, RemoveAll является потокобезопасным, поскольку он вызывает метод Clear внутри. Метод Clear вызывает HttpApplicationStateLock.AcquireWrite, а затем вызывает base.BaseClear и, наконец, освобождает блокировку.

также посмотреть на HttpApplicationState - Why does Race condition exist if it is thread safe?

+0

1. Что делать, если есть ситуация, когда несколько потоков уже «прочитать» HttpApplicationState, когда другой поток называет "RemoveAll? Или наоборот? 2. Даже метод Application.Set() получает внутреннюю блокировку. Но по-прежнему рекомендуется использовать Application.Lock и UnLock. Итак, по тем же причинам, почему нам не нужно (или не рекомендуется) использовать блокировку при вызове RemoveAll? – Learner

+0

Полный объект является потокобезопасным, как указано http://msdn.microsoft.com/en-us/library/system.web.httpapplicationstate.aspx. Просто взглянув на код, используя ILSpy, вы увидите, что в большинстве операций есть блокировки вокруг них. i.e. public object Get (string name) { \t объект result = null; \t this._lock.AcquireRead(); \t попытка \t { \t \t результат = основа.BaseGet (имя); \t} \t наконец \t { \t \t this._lock.ReleaseRead(); \t} \t результат возврата; } –