2011-11-26 12 views
6

Estamos utilizando el siguiente patrón para manejar el almacenamiento en caché de objetos universales para nuestra aplicación asp.net.¿Cómo implemento el almacenamiento en caché asincrónico?

private object SystemConfigurationCacheLock = new object(); 
public SystemConfiguration SystemConfiguration 
{ 
    get 
    { 
     if (HttpContext.Current.Cache["SystemConfiguration"] == null) 
      lock (SystemConfigurationCacheLock) 
      { 
       if (HttpContext.Current.Cache["SystemConfiguration"] == null) 
        HttpContext.Current.Cache.Insert("SystemConfiguration", GetSystemConfiguration(), null, DateTime.Now.AddMinutes(1), Cache.NoSlidingExpiration, new CacheItemUpdateCallback(SystemConfigurationCacheItemUpdateCallback)); 
      } 
     return HttpContext.Current.Cache["SystemConfiguration"] as SystemConfiguration; 
    } 
} 

private void SystemConfigurationCacheItemUpdateCallback(string key, CacheItemUpdateReason reason, out object expensiveObject, out CacheDependency dependency, out DateTime absoluteExpiration, out TimeSpan slidingExpiration) 
{ 
    dependency = null; 
    absoluteExpiration = DateTime.Now.AddMinutes(1); 
    slidingExpiration = Cache.NoSlidingExpiration; 
    expensiveObject = GetSystemConfiguration(); 
} 

private SystemConfiguration GetSystemConfiguration() 
{ 
    //Load system configuration 
} 

El problema es que cuando está bajo carga (~ 100.000 usuarios) vemos un gran salto en TTFB como los bloques de CacheItemUpdateCallback todos los otros hilos de ejecución hasta que haya terminado la actualización de la memoria caché de la base de datos.

Así que lo que pensé que se necesita es una solución que cuando el primer hilo después de una expiración de la caché intenta acceder a él, un hilo asíncrono se disparó para actualizar la caché, pero todavía permite que todos los otros hilos de ejecución para leer desde la edad caché hasta que se haya actualizado correctamente.

¿Hay algo incorporado en .NET Framework que pueda manejar de forma nativa lo que estoy pidiendo, o tendré que escribirlo desde cero? Sus pensamientos favor ...

Un par de cosas ...

El uso de la HttpContext.Current.Cache es incidental y no necesariamente esencial, ya tenemos ningún problema con los miembros privados en un producto único a mantener los datos en caché.

Por favor, no comenten los tiempos de caché, la eficacia de SPROC, por qué estamos en el almacenamiento en caché, etc., ya que no es relevante. ¡Gracias!

Respuesta

0

Así que resulta después de varias horas de investigación que el problema no es la CacheItemUpdateCallback bloqueando otros hilos como se pensaba originalmente, de hecho lo hizo exactamente lo que quería que forma asíncrona, pero fue el recolector de basura que detuvo todo para limpiar el LOH.

+0

y la solución se a? – orjan

+0

No utilizar este patrón para almacenar objetos que posteriormente podrían terminar en LOH. –

Cuestiones relacionadas