只是想知道是否有人明确知道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; }
}
Run Code Online (Sandbox Code Playgroud)
这是语言属性中使用的子类
public class Language
{
public string Name { get; set; }
public string Code { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
根据Reflector,HttpRuntime.Cache
根本没有序列化数据,它只是将它存储在内存中Hashtable
.
你说你在自己的单例对象中包含对缓存的调用.你为什么这么做?HttpRuntime.Cache
是一个静态属性,所以你的包装器方法也可以是静态的.
有关发生此缓存异常的环境的更多详细信息。
我有一个 ASP.net 用户控件,它代表页面上的选项卡式容器。该控件包含用户选择的主题列表。对于用户选择的每个主题,此控件都会为该主题创建一个新选项卡,其中包含与该主题相关的文档。
该控件利用 ASP.net 提供的 LoadControl 方法创建新选项卡。然后,它从列表中为新创建的选项卡控件分配一个主题。每个选项卡控件都知道如何查找其指定主题的文档。
正是在此选项卡控件中实现了缓存。用于缓存文档列表的缓存键对于查看主题的用户的站点+主题+性别+年龄来说是完全唯一的。这允许符合该条件的所有用户在整个站点上缓存和检索文档列表。
当文档列表被传递到缓存时,它们是通过常规旧对象引用传递的(即列表文档 = _documents)。但当从缓存中拉出时,列表为空。
尽管每个选项卡控件都是同一用户控件的自己的实例,并且选项卡控件中使用的所有变量都是该控件私有的,并且应该特定于该控件。我已经筋疲力尽了,尽管事实上各个选项卡不可能覆盖彼此的私人列表,但我认为一定存在某种疯狂的参考错误,如果是我需要的情况停止使用缓存中引用的对象,只向缓存发送我试图存储的列表的全新副本。
然后,我对 List<> 使用以下扩展方法,并在每个列表传递到缓存时克隆它们。这使得传递到缓存的所有项目都是全新的对象,在内存中拥有自己的空间以及对该内存的唯一引用。
修复。缓存现在可以工作了。现在返回的列表与添加到缓存中的列表完全相同。我不知道为什么这会产生影响,如果有人有任何想法,我很乐意听到他们。
/// <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();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3672 次 |
最近记录: |