MemoryCache Empty: возвращает ноль после установки - PullRequest
51 голосов
/ 15 сентября 2011

У меня проблема с приложением 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"]);

Когда он работает, предсказуемо выводится «fred».Однако, когда проблема начинает возникать, несмотря на Set(), значение MemoryCache.Default["myname"] равно нулю.Я могу доказать это, установив точку останова в строке Response.Write() и непосредственно установив и считав из кеша с помощью Immediate Window - он просто не установит его и останется нулевым!Тогда единственный способ заставить его работать снова - это вызвать перезапуск 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 ]

68 голосов
/ 30 марта 2013

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

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

Еще одна хорошая новость в том, что это исправление перенесено в .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

6 голосов
/ 04 марта 2013

У нас та же проблема.Я подтверждаю, что через некоторое время кеш стал ликвидным.Это личное поле _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 это вызывает выгрузку домена, но сохраняет кэш в памяти (я не уверен, если это возможно).

3 голосов
/ 22 ноября 2012

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

2 голосов
/ 22 марта 2013

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

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 входит вСостояние уничтожения Магически

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

1 голос
/ 15 сентября 2011

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

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

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

...