ASP.NET: HttpRuntime.Cache сбрасывается при сохранении WebConfigurationManager - это ошибка? - PullRequest
1 голос
/ 20 октября 2010

Недавно я экспериментировал с кэшированием объектов с HttpRuntime.Cache, и у меня было общее впечатление, что если я "добавлю" что-то в кеш, как это:

HttpRuntime.Cache.Insert("Test", "This is a test!", null, 
     Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, 
     CacheItemPriority.NotRemovable, new CacheItemRemovedCallback(FileChanged));

что флаги «NotRemovable» и «NoExpiration» сохранят объект в памяти на время действия приложения. Но обнаружил, что в конце некоторых запросов к странице HttpRuntime.Cache будет полностью пустым!

Прослеживая и устанавливая точку останова внутри моего Callback «FileChanged», я мог видеть, что действительно что-то «удаляло» мой объект (и все остальные объекты в кэше), но я не мог понять, почему. Так что в конце концов я начал отключать другие вещи, которые, как я думал, могут повлиять на эту подсистему.

В конце концов я закомментировал строку:

WebConfigurationManager.OpenWebConfiguration("~").Save;

Я в основном извлекал данные из "web.config" в регионе AppSettings, но иногда записывал обратно в AppSettings и сохранял изменения, используя приведенную выше команду. Из чтения я узнал, что «web.config» кэшируется, но сохранение моих изменений в нем не должно сбрасывать весь HttpRuntime.Cache, верно?

Это ошибка? Или эти два кэша каким-то образом связаны так, что я должен знать об этом?

РЕДАКТИРОВАТЬ:

Хорошо, я сделал это супер воспроизводимым, если кто-то хочет попробовать это на своей собственной машине. (Я использую VS2008 Pro с MVC2 для .NET 3.5) Просто запустите новый проект MVC2 и вставьте следующее в HomeController поверх того, что уже есть:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Configuration;
using System.Configuration;

namespace BackButtonTest.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        private string MESSAGE = "Message";
        public ActionResult Index()
        {
            ViewData[MESSAGE] = HttpRuntime.Cache.Get(MESSAGE);
            Configuration Config = WebConfigurationManager.OpenWebConfiguration("~");
            Config.AppSettings.Settings.Add("SomeKey", "SomeValue");
            Config.Save();
            return View();
        }

        public ActionResult About()
        {
            HttpRuntime.Cache[MESSAGE] = "This is pulled from the HttpRuntime.Cache";
            return View();
        }
    }
}

Затем выполните следующие действия:

  1. Запустите приложение в режиме отладки.
  2. Нажмите на ссылку «О нас». Это загружает строку в кэш.
  3. Нажмите на ссылку «Домой». Строка извлекается из кэша и застревает в словаре ViewMessage. Некоторая пара ключ / значение записывается в web.config и сохраняется. Строка из кэша должна появиться на домашней странице.
  4. Снова нажмите ссылку «Домой». Строка должна быть извлечена из кеша, но это не так.
  5. Остановка программы. Закомментируйте 3 строки, начинающиеся с «Config». Перезапустите программу.
  6. Попробуйте повторить шаги с 1 по 4. Обратите внимание, что HttpRuntime.Cache не был очищен.

Странно, да?

1 Ответ

2 голосов
/ 20 октября 2010

Запись в ваш web.config заставит приложение перезапуститься, и, скорее всего, события для очистки кэша, состояния сеанса in-proc и т. Д. УйдутПопробуйте записать какой-нибудь журнал в global.asax Application_End (или как там у метода :))

...