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()
выбрасывает исключение, ваша блокировка будет выпущена без каких-либо проблем, позволяя другим потокам продолжить выполнение.
Коллекция Cache была сделана Microsoft потоком. Внешняя блокировка не требуется. –
Кэш, являющийся потокобезопасным, гарантирует простоту несовместимости. Посмотрите пример кода выше. Если у вас нет инструкции 'lock', то несколько потоков будут вызывать' getValue() 'в то же время, независимо от того, кеш является потокобезопасным или нет. –
И я удивляюсь, почему причина в нижнем положении, заявив, что «этот ответ не полезен». В самом деле? –