2010-01-29 14 views
6

Solo me pregunto si alguien sabe definitivamente cuál es la serialización predeterminada utilizada por ASP.net HttpRuntime.Cache? ¿Es Binario, XML, algo más?¿Cuál es la serialización predeterminada utilizada por ASP.net HttpRuntime.Cache

Pregunto porque tengo una situación en la que estoy rellenando una Lista genérica con múltiples objetos del mismo tipo personalizado. El tipo personalizado es un POCO, no hay nada especial al respecto. Todas sus propiedades son públicas con {get; conjunto; }, es público, no tiene herencia, no tiene interfaces. De hecho, es mucho menos complicado que muchos otros objetos que almacenamos en caché que funcionan sin problemas. He intentado agregar el atributo [Serializable] a la clase personalizada y no tiene ningún efecto.

Agrego la lista a la memoria caché con una clave única. La lista se ha verificado como completada antes de que se inserte en la memoria caché, también se ha verificado que los objetos de la lista se han rellenado. Pero cuando la lista se retira de la memoria caché, es una lista vacía (NO NULA), simplemente no tiene elementos. Esto significa que la lista se está agregando a la memoria caché y es recuperable, pero por alguna razón la memoria caché tiene problemas para serializar los objetos en la lista.

Acabo de encontrar este raro extraño ya que tengo otra lista de objetos personalizados que son mucho más complicados (que consisten en Herencia, Interfaces y también contienen Propiedades que son listas genéricas de otros objetos complejos) y el almacenamiento en caché de esas listas sin problema

Tanto la lista de trabajo como la de no trabajo se administran en clases de C# fuera de los controles de usuario de ASP.net que consumen los datos en caché. Ambas clases de manejo de caché llaman a la misma instancia singleton de la clase Cache Manager que envuelve HttpRuntime.Cache para proporcionar métodos tipeados para extraer y empujar objetos en el caché.

Cualquiera tiene alguna idea de lo que podría causar que esto suceda. Lo único que puedo decir es que la propiedad 'Blurb' del objeto Document puede contener HTML, pero si ASP.net usa serialización binaria para el caché, no veo cómo esto podría hacer nada.

Aquí es la clase

public class Document 
{ 
    public string ContentTypeId { get; set; } 
    public string ContentId { get; set; } 
    public bool IsCustom { get; set; } 
    public Language DocLanguage { get; set; } 
    public string RegularTitle { get; set; } 
    public string InvertedTitle { get; set; } 
    public string Blurb { get; set; } 
} 

Aquí está la subclase utilizado en el lenguaje Propiedad

public class Language 
{ 
    public string Name { get; set; } 
    public string Code { get; set; } 
} 
+0

+1 ¡Buena pregunta! –

Respuesta

0

Un poco más de detalles con respecto al entorno en el que se está produciendo esta anomalía de almacenamiento en caché.

Tengo un control de usuario ASP.net que representa un contenedor con pestañas en la página. Este control contiene una lista de temas seleccionados por el usuario. Para cada tema que el usuario ha seleccionado, este control crea una nueva pestaña para ese tema que contiene documentos relacionados con ese tema.

El control crea la nueva pestaña utilizando el método LoadControl provisto por ASP.net. A continuación, asigna al Control de Pestañas recién creado un tema de su lista. Cada control de pestañas sabe cómo localizar documentos para su tema asignado.

Está dentro de este control de tabulación donde se implementó el almacenamiento en caché.La clave de caché utilizada para almacenar en caché las listas de documentos es completamente exclusiva del Sitio + Tema + Género + Edad del usuario que visualiza el tema. Esto permite que las listas de documentos sean almacenadas en caché y recuperadas en todo el sitio por todos los usuarios que se ajusten a esos criterios.

Bueno, cuando las listas de documentos se pasaron a la memoria caché, fueron pasadas por referencias de objeto antiguas regulares (es decir, documentos de lista = _documentos). pero cuando se saca de la memoria caché, la lista estaba vacía.

Aunque cada control de pestañas es su propia instancia del mismo control de usuario y todas las variables utilizadas en el control de pestañas son privadas para ese control y deben ser específicas para ese control. Golpeé el final de la cuerda y, a pesar del hecho de que no había forma de que las pestañas individuales pudieran sobreescribir las listas privadas de los demás, decidí que tenía que haber algún tipo de error de referencia loco y si ese era el caso que necesitaba dejar de usar los objetos referenciados en el caché y solo enviar al caché copias completamente nuevas de las listas que estaba tratando de almacenar.

Luego utilicé el siguiente método de extensión para la Lista <> y cloné cada lista a medida que se pasaban a la memoria caché. Esto hizo que todos los elementos pasados ​​a la memoria caché fueran objetos nuevos con su propio espacio en la memoria con sus propias referencias únicas a esa memoria.

CORREGIDO IT. EL CACHÉ AHORA FUNCIONA. Las listas ahora se devuelven exactamente como se agregaron a la memoria caché. No tengo idea de por qué esto marcaría la diferencia, si alguien tiene alguna idea, me encantaría escucharla.

/// <summary> 
    /// Clones the specified list to clone. 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="listToClone">The list to clone.</param> 
    /// <returns></returns> 
    public static IList<T> Clone<T>(this IList<T> listToClone) where T : ICloneable 
    { 
     return listToClone.Select(item => (T)item.Clone()).ToList(); 
    } 
5

De acuerdo con reflector, HttpRuntime.Cache no serializa los datos en absoluto, simplemente se almacena en la memoria en un Hashtable.

Usted dice que ajusta las llamadas al caché dentro de su propio objeto singleton. ¿Por qué haces esto? HttpRuntime.Cache es una propiedad estática, por lo que los métodos de contenedor también pueden ser estáticos.

+0

Es una aplicación web de empresa y fue una decisión arquitectónica tomada por aquellos con mucho más poder que yo :). – Schleichermann

+1

A menos que tenga evidencia de lo contrario, sospecho que el código del contenedor antes del tiempo de ejecución de ASP.NET. He escrito este tipo de código de arquitectura (¡incluido mi propio contenedor de caché!), Y sé lo difícil que es hacerlo bien. ¿Tal vez lo está usando de una manera que no fue diseñado para manejar? Sugiero tomar el asunto con los autores de su clase contenedora. –

0

Los caches en general no serializan ni clonan los objetos que colocas en ellos. Simplemente asocian una clave con el objeto que pasa. Y como las Listas son tipos de referencia, cualquier cambio que realice en la lista estará visible cuando la clave se use para recuperarla de la memoria caché. Así que supongo que está eliminando elementos de la lista después de insertarlos. Esta es la razón por la que el clon en la inserción lo resolvió.

Cuestiones relacionadas