2012-04-22 3 views
6

Класс Application в asp.net имеет Lock механизм для обеспечения безопасности потоков.Применение против кеша: механизм блокировки

Как известно, к Application можно получить доступ по всему миру.

образец:

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

ок.

но

Также Cache глобально доступной (и оленья кожа имеет механизм блокировки, а также используется для удаления/добавления элементов)

так почему Application имеет механизм блокировки и Cache не ли?

ответ

6

Application является хранилищем данных, оставшимся от старой технологии ASP. Он имеет один глобальный замок. Когда вы вызываете Application.Lock(), все обращения к объекту Application во всех потоках блокируются.

С другой стороны, новый объект Cache, который был представлен с помощью ASP.NET, позволяет использовать собственную семантику блокировки. Вы можете использовать инструкцию NET lock для обеспечения поточного доступа к объекту Cache, сохраняя при этом ваше веб-приложение как можно более параллельным. Оператор lock намного безопаснее, поскольку блокировка гарантированно будет выпущена при выходе из блока lock. Объект приложения не гарантирует этого. Кэш также обеспечивает механизмы автоматического истечения срока действия, которые гораздо более подходят для кеша. Он также может истекать ключами на основе контрактов зависимостей и необязательных приоритетов, которые, конечно, отсутствуют.

Я не вижу причины использовать Application над Cache объект.

Пример: предположим, что у вас есть сто элементов в кеше, и у вас есть один элемент, который вы хотите сохранить в кеше, если он еще не существует. При использовании Application, вы делаете это:

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

В этом случае все обращения к объекту Application блокируются, даже если они совершенно не имеет значения. И в случае, если getValue() вызывает исключение, ваше приложение зависает, потому что блокировка не выпущена. Вам необходимо обернуть try .. finally, чтобы убедиться, что это безопасно.

С другой стороны, при использовании Cache объекта, вы делаете это:

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

В этом случае только блоки кода, которые требуют доступа к myLockObject будет ждать. Другие, которые получают доступ к Cache, будут работать параллельно. И в случае, если getValue() выбрасывает исключение, ваша блокировка будет выпущена без каких-либо проблем, позволяя другим потокам продолжить выполнение.

+1

Коллекция Cache была сделана Microsoft потоком. Внешняя блокировка не требуется. –

+3

Кэш, являющийся потокобезопасным, гарантирует простоту несовместимости. Посмотрите пример кода выше. Если у вас нет инструкции 'lock', то несколько потоков будут вызывать' getValue() 'в то же время, независимо от того, кеш является потокобезопасным или нет. –

+0

И я удивляюсь, почему причина в нижнем положении, заявив, что «этот ответ не полезен». В самом деле? –

Смежные вопросы