Память кеша пуста сразу после добавления объекта - PullRequest
8 голосов
/ 21 октября 2011

Я сталкиваюсь со странной проблемой с ASP.NET MemoryCaching в приложении MVC 3 ASP.NET.

Каждый раз, когда выполняется действие, я проверяю, действительно ли его LoginInfo хранится в MemoryCache (кодбыл упрощен, но ядро ​​выглядит следующим образом):

[NonAction]
protected override void OnAuthorization(AuthorizationContext filterContext) {
  Boolean autorizzato = false;
  LoginInfo me = CacheUtils.GetLoginData(User.Identity.Name);
  if (me == null)
  {
    me = LoginData.UserLogin(User.Identity.Name);
    CacheUtils.SetLoginInfo(User.Identity.Name, me);
  }
  // Test if the object is really in the memory cache
  if (CacheUtils.GetLoginData(User.Identity.Name) == null) {
     throw new Exception("IMPOSSIBLE");
  } 
}

GetLoginInfo:

 public static LoginInfo GetLoginData(String Username)
        {
            LoginInfo local = null;
            ObjectCache cache = MemoryCache.Default;
            if (cache.Contains(Username.ToUpper()))
            {
                local = (LoginInfo)cache.Get(Username.ToUpper());
            }
            else
            {
                log.Warn("User " + Username + " not found  in cache");
            }
            return local;
        }

SetLoginInfo:

        public static void SetLoginInfo (String Username, LoginInfo Info)
        {
            ObjectCache cache = MemoryCache.Default;
            if ((Username != null) && (Info != null))
            {
                if (cache.Contains(Username.ToUpper()))
                {
                    cache.Remove(Username.ToUpper());
                }
                cache.Add(Username.ToUpper(), Info, new CacheItemPolicy());
            }
            else
            {
                log.Error("NotFound...");
            }
       }

Код довольнопросто, но иногда (совершенно случайно), сразу после добавления LoginInfo в MemoryCache, это приводит к пустым результатам, только что добавленный объект отсутствует, поэтому я получил исключение.

Я тестирую это оба на Cassiniи IIS 7, похоже, не связан с возможностью повторного использования AppPool (включен в IIS 7), я протестировал несколько политик кэширования, но не могу заставить его работать

Что я пропускаю / не выполняю?

PS: прости меня за мой плохой английский

Ответы [ 3 ]

3 голосов
/ 28 сентября 2012

Глядя на код для MemoryCache с использованием декомпилятора, мы видим следующую частную функцию

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

Существует необработанная настройка обработчика исключений каждым MemoryCache для текущего домена Thread.GetDomain(), поэтому, если в вашем приложении есть какое-либо исключение, которое не перехватывается, что может быть обычным явлением на веб-сайте, оно всегда удаляет MemoryCache и не может быть повторное использование, это особенно актуально для приложений IIS, в отличие от приложений Windows, которые просто выходят при незапланированных исключениях.

1 голос
/ 25 апреля 2014

Я полагаю, что вы столкнулись с проблемой, которую Скотт Хансельман назвал ошибкой .NET 4.Смотрите здесь: MemoryCache Empty: Возвращает ноль после установки

1 голос
/ 08 мая 2012

MemoryCache имеет ограниченный размер.Для экземпляра По умолчанию это не эвристическое значение (в соответствии с MSDN ).

Вы пытались установить Приоритет свойство в CacheItemPolicy экземпляр в NotRemovable ?

Вы можете иметь состояние гонки, поскольку последовательность Contains-Remove-Add в SetLoginInfo имеет значениене атомарный - попробуйте использовать метод Set .

Btw.вы работаете над веб-приложением, так почему бы не использовать вместо него System.Web.Caching.Cache ?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...