Блокировка HttpRuntime.Cache для отложенной загрузки - PullRequest
3 голосов
/ 15 января 2009

У нас есть веб-сайт под управлением .NET 2.0, и мы начали использовать ASP.Net HttpRuntime.Cache для хранения результатов частых поисков данных, чтобы сократить доступ к нашей базе данных.

Отрывок:

 
lock (locker)
{
    if (HttpRuntime.Cache[cacheKey] == null)
    {
        HttpRuntime.Cache.Insert(cacheKey, GetSomeDataToCache(), null, DateTime.Today.AddDays(1), Cache.NoSlidingExpiration);       
    }
    return ((SomeData)HttpRuntime.Cache[cacheKey]).Copy();
}

Мы пессимистически блокируем всякий раз, когда хотим посмотреть на кеш. Тем не менее, я видел различные блоги, размещенные в Интернете, предлагающие блокировку после проверки значения кэша, чтобы не понести накладные расходы на блокировку. Это не кажется правильным, так как другой поток мог записать в кеш после проверки.

Итак, наконец, мой вопрос - каков «правильный» способ сделать это? Мы даже используем правильный объект синхронизации потока? Мне известно о ReaderWriterLockSlim (), но мы работаем с .NET 2.0.

Ответы [ 4 ]

9 голосов
/ 15 января 2009

Насколько я знаю, объект Cache является поточно-ориентированным, поэтому блокировка вам не понадобится.

5 голосов
/ 15 января 2009

Объект Cache в .NET является потокобезопасным, поэтому блокировка не требуется. Справка: http://msdn.microsoft.com/en-us/library/system.web.caching.cache.aspx.

1 голос
/ 11 июля 2009

Ваш код, вероятно, заставляет вас думать, что этот элемент будет кэшироваться в течение 1 дня, и ваша последняя строка всегда будет предоставлять вам эти данные, но это не так. Как говорили другие, операции кеширования синхронизированы, поэтому в этот момент блокировать не следует.

Найдите здесь правильный способ сделать это .

0 голосов
/ 23 мая 2015

Резьба безопасна. Означает ли это, что все другие процессы ждут когда-нибудь, когда ваш код завершит работу?

Потокобезопасен - вы можете быть уверены, что выбранный вами элемент не будет «разрезан пополам» или частично снесен обновлением кеша в то время, когда вы читаете элемент.

item = cache.Get(key);

Но все, что вы делаете после этого - другой поток может работать с кешем (или любым другим общим ресурсом). Если вы хотите что-то сделать с кешем, основываясь на том, что выбранный вами элемент равен нулю или нет, я не был бы на 100% уверен, что он еще не исправлен другим экземпляром вашего собственного кода, так как несколько инструкций процессора впереди обслуживают другого читателя на той же странице вашего онлайн-журнала.

Вам нужна удача. Риск того, что другие процессы будут беспокоиться об одном и том же объекте кэша, не атомарном, в нескольких строках кода, случайным образом невелик. Но если это произойдет, вам будет трудно понять, почему образ Шевроле иногда является маленьким чемоданом со второй страницы.

...