ASP.net HttpRuntime.Cache使用的默认序列化是什么

时间:2010-01-29 15:31:52

标签: asp.net caching

只是想知道是否有人明确知道ASP.net HttpRuntime.Cache使用的默认序列化是什么?是二进制,XML还是别的什么?

我问,因为我遇到的情况是我使用相同自定义类型的多个对象填充通用List。自定义类型是POCO,没有什么特别之处。它的所有属性都是公开的{get;组;它是公共的,它没有继承,它没有接口。事实上,它比我们正在缓存的许多其他对象复杂得多,没有问题。我已经尝试将[Serializable]属性添加到自定义类,它没有任何效果。

我使用唯一键将列表添加到缓存中。在将列表插入缓存之前,已对列表进行了验证,列表中的对象也已经过验证。但是当列表从缓存中拉回时它是一个空列表(NOT NULL),它根本没有任何项目。这意味着列表正被添加到缓存中并且是可检索的,但由于某种原因,缓存在序列化列表中的对象时出现问题。

我发现这怪异怪异,因为我有另一个自定义对象列表,它们更复杂(包括继承,接口,还包含属性,这些属性是其他复杂对象的通用列表),并且这些列表的缓存无需工作问题。

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

任何人都有任何想法会导致这种情况发生。我唯一可以解决的是Document对象的'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; }
}  

这是语言属性

中使用的子类
public class Language
{
    public string Name { get; set; }
    public string Code { get; set; }
}

3 个答案:

答案 0 :(得分:5)

根据Reflector,HttpRuntime.Cache根本没有序列化数据,它只是将它存储在Hashtable的内存中。

你说你在自己的单例对象中包装对缓存的调用。你为什么这么做? HttpRuntime.Cache是一个静态属性,所以你的包装器方法也可以是静态的。

答案 1 :(得分:0)

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

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

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

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

当文档列表传递到缓存时,它们通过常规的旧对象引用传递(即List documents = _documents)。但是当从缓存中拉出时,列表是空的。

虽然每个选项卡控件都是它自己的同一个用户控件的实例,但选项卡控件中使用的所有变量都是该控件的私有,并且应该特定于该控件。我打我的绳子的末端,尽管是没有办法的各个选项卡可以在书写每个人的私人名单,我决定必须有某种疯狂参考错误发生的情况,如果这是我需要的情况下,停止使用缓存中引用的对象,只发送缓存完全新的我试图存储的列表的副本。

然后,我使用以下扩展方法为List<>并在每个列表传递到缓存时克隆它们。这使得传递到缓存的所有项目都是全新的对象,在内存中有自己的空间,并具有对该内存的唯一引用。

固定IT。现在的缓存工作。现在返回的列表与添加到缓存中的列表完全相同。我不知道为什么这会有所作为,如果有人有任何想法,我很乐意听到它们。

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

答案 2 :(得分:0)

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

相关问题