2009-04-16 17 views
20

En el pasado, establecí un bloqueo para acceder al mecanismo HttpRuntime.Cache. No estoy seguro de si realmente había investigado el problema en el pasado y lo cerré ciegamente con un candado.Prácticas recomendadas de HttpRuntime.Cache

¿Crees que esto es realmente necesario?

+0

http://stackoverflow.com/questions/447705/locking-httpruntime-cache-for-lazy-loading Parece que el caché es seguro para subprocesos –

+0

idioma/plataforma? – Javier

Respuesta

2

No creo que sea necesario ajustar el acceso a la propiedad HttpRuntime.Cache con un candado, ya que la propiedad .Cache es estática y también es segura para subprocesos.

Hay muchas formas diferentes de acceder al objeto Cache (HttpRuntime.Cache, HttpContext.Current.Cache, Page.Cache, etc.). Todos acceden al mismo objeto de caché, ya que solo hay un objeto de caché por dominio de aplicación, ya que es efectivamente un objeto Singleton seguro para subprocesos.

10

Este artículo sugiere una cerradura se debe utilizar:

http://msdn.microsoft.com/en-us/magazine/cc500561.aspx

Cita:

El problema es que si usted tiene una consulta que tarda 30 segundos y ya está ejecutando la página cada segundo, en el tiempo que lleva llenar el elemento de caché , entran otras 29 solicitudes, , todas las cuales intentarán a llene el elemento de caché con sus propias consultas a la base de datos. Para resolver este problema , puede agregar un bloqueo de subproceso a detener las otras ejecuciones de página desde solicitando los datos de la base de datos.

Aquí es su fragmento de código:

// check for cached results 
object cachedResults = ctx.Cache["PersonList"]; 
ArrayList results = new ArrayList(); 

if (cachedResults == null) 
{ 
    // lock this section of the code 
    // while we populate the list 
    lock(lockObject) 
    { 
    cachedResults = ctx.Cache["PersonList"]; 
    // only populate if list was not populated by 
    // another thread while this thread was waiting 
    if (cachedResults == null) 
    { 
     cachedResults = ... 
     ctx.Cache["PersonList"] = cachedResults; 
    } 
    } 
} 

no he probado este código, pero estaría muy interesado en escuchar a alguien que ha evaluado este enfoque en un entorno de producción.

+11

No creo que esto sea necesario en términos de seguridad del hilo de caché: es más para evitar que los accesos múltiples a la base de datos ejecuten una consulta potencialmente costosa. – zcrar70

+1

Estoy de acuerdo con usted. – frankadelic

+5

Solo un pequeño pero importante error en el ejemplo: entre el bloqueo (lockObject) y el if (cachedResults == null), el elemento almacenado en caché debe recuperarse nuevamente. Vea esto http: // stackoverflow.com/questions/39112/what-is-the-best-way-to-lock-cache-in-asp-net para un ejemplo apropiado. –

2

No creo que el bloqueo sea la respuesta al problema a continuación, especialmente en el entorno de producción, donde tiene varios servidores ejecutando su aplicación.

El problema es que si tiene una consulta que demora 30 segundos y está ejecutando la página cada segundo, en el tiempo necesario para completar el elemento de caché, aparecerán otras 29 solicitudes, todas las cuales intentará llenar el elemento de caché con sus propias consultas a la base de datos. Para resolver este problema, puede agregar un bloqueo de hilo para evitar que otras ejecuciones de la página soliciten los datos de la base de datos.

Cuestiones relacionadas