MemoryCache Empty: возвращает ноль после установки

У меня проблема с приложением MVC 3, использующим новую.NET 4 System.Runtime.Caching MemoryCache. Я замечаю, что после, казалось бы, непредсказуемого времени, он перестает кэшировать вещи и действует как пустой. Рассмотрим этот фрагмент кода, который я взял прямо из тестового представления в ASP.NET MVC:

MemoryCache.Default.Set("myname","fred", new CacheItemPolicy() { SlidingExpiration = new TimeSpan(0,5,0) });
Response.Write(MemoryCache.Default["myname"]);

Когда это работает, предсказуемо печатается "Фред". Однако, когда проблема начинает возникать, несмотря на Set(), значение MemoryCache.Default["myname"] нулевой. Я могу доказать это, установив точку останова на Response.Write() прямая установка и чтение из кеша с помощью окна Immediate - он просто не будет установлен и останется нулевым! Тогда единственный способ заставить его работать снова - это перезапустить AppDomain.

Интересно, что я могу спровоцировать возникновение проблемы, когда приложение работает нормально, взломав Response.Write() линия и бег MemoryCache.Default.Dispose(), После этого MemoryCache.Default сам по себе не равен нулю (почему это так?), Но не будет сохранять на нем ничего установленного. Это не вызывает никаких ошибок, но ничего не спасет.

Кто-нибудь может это проверить и объяснить? Как я полагаю, я обнаружил, что когда приложение перестает работать само по себе, что-то MemoryCache.Default, но это не я!


ОБНОВИТЬ

Ну, мне надоел этот пробник сейчас! CLRProfiler, похоже, не работает с MVC 3. Инструмент SciTech CLR был хорош - как и RedGate ANTS. Но все, что мне сказали, это то, что объект MemoryCache чем-то уничтожен! Я также доказал (с помощью печати временной метки), что PartialView на моей странице, который должен быть кэширован (задан OutputCacheAttribute), перестает кэшироваться через несколько минут - он начинает обновляться при каждом обращении к странице. Просто чтобы прояснить среду, я работаю прямо на сервере IIS 7.5 на моей рабочей станции, на которой работает Win 7 Ultimate. Упомянутые выше инструменты памяти предполагают, что я использую только около 9 МБ памяти в терминах объектов в игре.

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

У меня возникает ощущение, что MemoryCache и OutputCache не гарантированы для работы с MVC 3...

5 ответов

Решение

Итак, вот некоторые новости. Мы рассмотрели это и ДА, это ошибка в.NET 4.

Хорошая новость заключается в том, что она была исправлена ​​в.NET 4.5, поэтому, если вы можете, обновите установку до.NET 4.5, и все готово.

Другая хорошая новость заключается в том, что это исправление перенесено в.NET 4 и будет доступно в виде QFE (Быстрое исправление... одноразовое исправление, которое вы примените) #578315. Это было перенесено / исправлено всего несколько дней назад, и оно должно быть как можно скорее. Я постараюсь получить точную дату, но это скоро.

Другая хорошая новость заключается в том, что есть обходной путь в.NET 4 до QFE. Обходной путь странный, но он может разблокировать вас.

using (ExecutionContext.SuppressFlow())     {
          // Create memory cache instance under disabled execution context flow
         return new YourCacheThing.GeneralMemoryCache(…);
}

Надеюсь это поможет.

ОБНОВЛЕНИЕ: исправление http://support.microsoft.com/kb/2828843 и вы можете запросить его здесь: https://support.microsoft.com/contactus/emailcontact.aspx?scid=sw;%5BLN%5D;1422

У нас та же проблема. Я подтверждаю, что через некоторое время кеш стал ликвидным. Это личное поле _disposed стал 1. Я уверен, что у меня нет вызова кеша. Уничтожить в моем коде. Но когда я посмотрел код MemoryCache с Reflector, то увидел, что в конструкторе он подписывается на два события

domain.DomainUnload += eventHandler;
domain.UnhandledException += exceptionEventHandler;

private void OnAppDomainUnload(object unusedObject, EventArgs unusedEventArgs)
{
  this.Dispose();
}

private void OnUnhandledException(object sender, UnhandledExceptionEventArgs eventArgs)
{
  if (!eventArgs.IsTerminating)
    return;
  this.Dispose();
}

Оба из этих обработчиков событий имеют вызов Dispose. Может быть, после некоторой перезапуска домена в IIS это вызывает выгрузку домена, но сохраняет кэш в памяти (я не уверен, если это возможно).

Я испытывал точно такие же симптомы. Я наконец-то привел к использованию класса System.Web.Cache и подключению к HttpContext.Cache. Работает отлично последние 3 дня.

Смотрите также эти ссылки, связанные с той же проблемой.

MemoryCache удаляется после PollingInterval при использовании в WebApp в режиме Integrated Pipeline.

http://connect.microsoft.com/VisualStudio/feedback/details/764911/memorycache-gets-disposed-after-pollinginterval-when-used-in-webapp-in-integrated-pipeline-mode

MemoryCache магически переходит в состояние Disposed

http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/1233ffb3-6480-431b-94ca-1190f96cf5f6

MemoryCache автоматически изгонит предметы, если достигнет предела памяти. Это может произойти в вашем случае, у вас есть много элементов в кэше?

Вы можете контролировать пределы с помощью конфигурации. По умолчанию он оптимизируется на основе доступной памяти.

Конечно звонит Dispose остановит MemoryCache Экземпляр работает, поскольку он очистит все неуправляемые ресурсы, готовые к утилизации. Вы должны только позвонить Dispose если вы не собираетесь использовать MemoryCache больше Я не думаю, что это является необходимой проблемой в вашем случае, за исключением случаев, когда вы это называете.

Другие вопросы по тегам