2015-01-30 4 views
2

Когда я кешу объекта HttpContext Cache, мой объект исчезает при следующем чтении, и я должен повторно вставить объект во второй раз (не всегда, но в 90% случаев). После этого объект остается без проблем.Почему я должен поместить свой объект дважды в HttpContext Cache, прежде чем он сохранит его навсегда?

Вот что произошло:

  1. Начать отладку MVC проекта
  2. Прочитайте возраст из кэша
  3. возраст нулевой поэтому я поставил 50 в переменной, а затем вставьте его в cache
  4. CacheItemRemovedCallback выполняется сразу же после завершения реакции на клиента. Значение CacheItemRemovedReason является Removed
  5. обновления нажмите пользователь сразу
  6. Прочитайте возраст из кэша
  7. возраст по-прежнему нулевой так я поставил 50 в переменной, а затем вставьте его в кэш
  8. The пользователь немедленно нажмет обновить
  9. Прочтите возраст из кеша
  10. возраст наконец!

Почему у Cache есть эта проблема, чтобы сохранить объект в кеше на первой вставке?

Это поведение существует в .Net framework 3.5, 4.0, 4.5, 4.5.2.

Вот код:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     int? age = this.HttpContext.Cache.Get("age") as int?; 
     if (age == null) 
     { 
      age = 50; 

      this.HttpContext.Cache.Add("age", age, null, DateTime.Now.AddHours(5), TimeSpan.Zero, CacheItemPriority.Default, new CacheItemRemovedCallback(this.CacheItemRemovedCallback)); 
     } 
     return View(); 
    } 

    public void CacheItemRemovedCallback(String key, Object value, CacheItemRemovedReason reason) 
    { 
    } 
} 
+0

Есть ли причина, по которой вы не указали продолжительность кеша в Insert()? Этот предмет может быть взломан раньше, чем вы думаете. – StingyJack

+0

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

+1

Кэш никогда не бывает постоянным. Infinity не является значением по умолчанию, и в кеше будут удалены элементы, если они больше не нужны. Поставьте время в 1 час для кеша, и вы должны увидеть этот пункт в первый раз, когда вы его ожидаете. – StingyJack

ответ

2

Причина, почему мой кэшируются пункт был удален сразу после его вставки было потому, что AppDomain выгружается после первого звонка на веб-сайте. Улавливая событие разгрузки AppDomain, я смог узнать причину отключения. Антивирус просматривал файл веб-сайта, инициировавший событие FileChangesMonitorAppDomain, который затем вывел выгрузку из AppDomain.

Вот как определить причину, почему AppDomain разгружаться:

Global.asax

public class MvcApplication : System.Web.HttpApplication 
{ 
    protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 
     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
     RouteConfig.RegisterRoutes(RouteTable.Routes); 
     BundleConfig.RegisterBundles(BundleTable.Bundles); 

     AppDomain currentDomain = AppDomain.CurrentDomain; 
     currentDomain.DomainUnload += DomainUnloadEventHandler; 
    } 

    static void DomainUnloadEventHandler(object sender, EventArgs e) 
    { 
     var httpRuntimeType = typeof(HttpRuntime); 

     var httpRuntime = httpRuntimeType.InvokeMember(
      "_theRuntime", 
      BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField, 
      null, null, null) as HttpRuntime; 

     var shutDownMessage = httpRuntimeType.InvokeMember(
      "_shutDownMessage", 
      BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, 
      null, httpRuntime, null) as string; 

     string shutDownStack = httpRuntime.GetType().InvokeMember(
      "_shutDownStack", 
      BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, 
      null, httpRuntime, null) as string; 
    } 
} 

Вот что переменная shutDownMessage содержит:

_shutDownMessage: Change Notification for critical directories. 
bin dir change or directory rename 
HostingEnvironment initiated shutdown 
HostingEnvironment caused shutdown 
Change in C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\48a6542f\e317ebf6\hash\hash.web 

ли вы можете увидеть , файл hash.web является причиной AppDoma в разгрузке. Теперь, кто меняет этот файл? Оказывается, это антивирус. К деактивировать сканер On-Access McAfee, файл hash.web больше не был изменен, поэтому нет загрузки AppDomain. Задача решена!

Для получения дополнительной информации вы можете прочитать это blog post.