MemoryCache Empty: devuelve null después de ser configurado

Tengo un problema con una aplicación MVC 3 que está utilizando el nuevo .NET 4 System.Runtime.Caching MemoryCache. Noté que después de un tiempo aparentemente impredecible, deja de almacenar en caché cosas, y actúa como si estuviera vacío. Considere este pequeño código que tomé directamente de una vista de prueba en ASP.NET MVC:

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

Cuando está funcionando, predeciblemente se imprime “fred”. Sin embargo, cuando el problema comienza a ocurrir, a pesar del Set() , el valor de MemoryCache.Default["myname"] es nulo. Puedo probar esto estableciendo un punto de interrupción en la línea Response.Write() y configurando y leyendo directamente desde el caché usando la Ventana Inmediata – ¡Simplemente no lo configurará y se quedará nulo! La única manera de que funcione de nuevo es causar un reciclaje de AppDomain.

Curiosamente, puedo provocar que el problema se produzca cuando la aplicación está funcionando normalmente al interrumpir la línea Response.Write() y ejecutar MemoryCache.Default.Dispose() . Después de eso, MemoryCache.Default no es nulo en sí mismo (¿por qué es esto?), Pero no guardará nada establecido en él. No causa ningún error, pero simplemente no guardará nada.

¿Alguien puede verificar esto y explicar? Como creo que he descubierto, cuando la aplicación deja de funcionar por sí sola, algo es MemoryCache.Default , ¡pero no soy yo!


ACTUALIZAR

Bueno, estoy harto de este problema ahora! CLRProfiler no parece funcionar con MVC 3. La herramienta CLR de SciTech era buena, al igual que RedGate ANTS. ¡Pero todo lo que me dijeron fue que el objeto MemoryCache está siendo eliminado por algo ! También probé (a través de una impresión de marca de tiempo) que una Vista parcial en mi página que debe almacenarse en caché (especificada por OutputCacheAttribute) deja de almacenarse en caché después de unos minutos; comienza a actualizarse con cada llamada a la página. Solo para aclarar el entorno, me estoy ejecutando directamente en el servidor IIS 7.5 en mi estación de trabajo de desarrollo con Win 7 Ultimate. Las herramientas de memoria mencionadas anteriormente sugieren que solo estoy usando alrededor de 9 MB de memoria en términos de objetos en juego.

En mi desesperación, he cambiado mi código de almacenamiento en caché para buscar primero un HttpContext ambiente para engancharme y usar su funcionalidad de almacenamiento en caché, si hay una disponible. Las primeras pruebas muestran que esto es confiable, pero se siente como un hack desagradable.

Tengo la sensación de que MemoryCache y OutputCache no están garantizados para funcionar con MVC 3 …

Entonces, aquí hay algunas noticias. Analizamos esto y SÍ, este es un error en .NET 4.

La buena noticia es que se corrigió en .NET 4.5, por lo tanto, si puede, actualice su instalación a .NET 4.5 y será sólido.

La otra buena noticia es que esta solución ha sido retransmitida a .NET 4 y estará disponible como QFE (Solución rápida … correrá una solución única) # 578315. Fue backported / fixed hace unos días y debería estar fuera lo antes posible. Trataré de obtener una fecha exacta, pero es pronto.

La otra buena noticia es que hay una solución para esto en .NET 4 antes del QFE. La solución es extraña, pero podría desbloquearte.

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

Espero que esto ayude.

ACTUALIZACIÓN: el Hotfix es http://support.microsoft.com/kb/2828843 y puede solicitarlo aquí: https://support.microsoft.com/contactus/emailcontact.aspx?scid=sw;%5BLN%5D; 1422

Tenemos el mismo problema. Confirmo que después de un período de tiempo la memoria caché se eliminó. Su campo privado _disposed se convirtió en 1. Estoy seguro de que no tengo call to cache.Dispose en mi código. Pero cuando miré el código de MemoryCache con Reflector que vi, en el constructor se suscribe en dos eventos

 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(); } 

Ambos controladores de eventos tienen una llamada a Dispose. Puede ser después de un reciclaje de dominio en IIS que causa la descarga del dominio, pero mantiene el caché en la memoria (no estoy seguro si es posible).

He estado experimentando exactamente los mismos síntomas. Finalmente he resultado en el uso de la clase System.Web.Cache en su lugar y enganchándome en HttpContext.Cache. Ha funcionado perfectamente durante los últimos 3 días.

Ver también estos enlaces relacionados con el mismo problema.

MemoryCache se elimina después de PollingInterval cuando se usa en WebApp en modo Integrated Pipeline

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

MemoryCache get in Estado expuesto Mágicamente

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

MemoryCache desalojará automáticamente los elementos si alcanza su límite de memoria. Esto podría estar sucediendo en tu caso, ¿tienes muchos elementos en el caché?

Puede controlar los límites con la configuración . Por defecto, optimiza en función de la memoria disponible.

Ciertamente, llamar a Dispose detendrá el MemoryCache instancia de MemoryCache ya que limpiará todos los recursos no administrados listos para su eliminación. Solo debe llamar a Dispose si no tiene la intención de usar MemoryCache nunca más. No creo que sea necesario el problema en su caso, excepto cuando lo llame.