代码之家  ›  专栏  ›  技术社区  ›  Schleichermann

ASP.NET httpruntime.cache使用的默认序列化是什么

  •  6
  • Schleichermann  · 技术社区  · 16 年前

    只是想知道是否有人确切知道ASP.NET httpruntime.cache使用的默认序列化是什么?它是二进制的、XML的还是其他的?

    我这样问是因为我遇到了这样一种情况:我要用相同自定义类型的多个对象填充一个通用列表。自定义类型是POCO,没有什么特别的。它的所有属性都是带有get;set;的公共属性,它是公共的,它没有继承,它没有接口。事实上,它比我们正在缓存的许多其他无问题工作的对象要简单得多。我尝试将[serializable]属性添加到自定义类,但它没有任何效果。

    我用一个唯一的键将列表添加到缓存中。在将列表插入缓存之前,已验证它是否已填充,列表中的对象也已验证是否已填充。但是当列表从缓存中拉出时,它是一个空列表(不是空列表),它只是没有任何项。这意味着列表正在被添加到缓存中并且是可检索的,但是由于某种原因,缓存在序列化列表中的对象时遇到问题。

    我只是觉得这很奇怪,因为我有另一个自定义对象列表,它更复杂(包括继承、接口,还包含属性,这些属性是其他复杂对象的通用列表),这些列表的缓存工作没有问题。

    工作列表和非工作列表都在使用缓存数据的ASP.NET用户控件之外的C类中进行管理。这两个缓存处理类调用完全相同的缓存管理器类singleton实例,该实例包装httpruntime.cache,以提供用于将对象拉入和推入缓存的类型化方法。

    任何人都知道会发生什么。我唯一能理解的是,文档对象的“Blurb”属性可能包含HTML,但是如果ASP.NET对缓存使用二进制序列化,我看不出这会如何做。

    这是班级

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

    这是language属性中使用的子类

    public class Language
    {
        public string Name { get; set; }
        public string Code { get; set; }
    }
    
    3 回复  |  直到 14 年前
        1
  •  5
  •   Christian Hayter    16 年前

    根据反射镜, HttpRuntime.Cache 根本不序列化数据,它只将数据存储在内存中 Hashtable .

    您说您将对缓存的调用包装在自己的singleton对象中。你为什么这么做? httpruntime.缓存 是静态属性,因此包装方法也可以是静态的。

        2
  •  0
  •   Schleichermann    16 年前

    关于发生这种缓存异常的环境的更多细节。

    我有一个ASP.NET用户控件,它表示页面上的选项卡式容器。此控件包含用户选择的主题列表。对于每个主题,用户已选择此控件为该主题创建一个新选项卡,其中包含与该主题相关的文档。

    控件使用ASP.NET提供的LoadControl方法创建新选项卡。然后,它从新创建的选项卡控件的列表中分配一个主题。每个选项卡控件都知道如何为其分配的主题定位文档。

    它在实现缓存的这个选项卡控件中。用于缓存文档列表的缓存键对于查看主题的用户的站点+主题+性别+年龄是完全唯一的。这允许所有符合该条件的用户在整个站点缓存和检索文档列表。

    当文档列表被传递到缓存时,它们被常规的旧对象引用(即list documents=\u documents)传递。但当从缓存中提取时,列表是空的。

    尽管每个选项卡控件都是同一用户控件的自己的实例,并且在选项卡控件中使用的所有变量都是该控件的私有变量,并且应该特定于该控件。我走到了尽头,尽管每个选项卡都无法重写彼此的私有列表,但我还是决定要发生某种疯狂的引用错误,如果是这样的话,我需要停止在缓存中使用引用的对象,只将新的列表副本发送给缓存。尝试存储。

    然后,我对列表使用了以下扩展方法,并在将每个列表传递到缓存时克隆它们。这使得传递到缓存的所有项都是全新的对象,它们在内存中有自己的空间,并且对该内存有自己独特的引用。

    修理它。缓存现在可以工作了。现在返回的列表与添加到缓存的列表完全相同。我不知道为什么这会有什么不同,如果有人有任何想法,我很想听到他们。

        /// <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();
        }
    
        3
  •  0
  •   bmm6o    14 年前

    缓存通常不会序列化或克隆您放入其中的对象。它们只是将一个键与您传入的对象相关联。而且由于列表是引用类型,所以当使用键从缓存中检索时,对列表所做的任何更改都将可见。所以我猜你是在插入列表后从列表中删除项目。这就是“插入时克隆”解析它的原因。

    推荐文章