在反序列化期间,在泛型类内部调用泛型方法的委托将CPU挂起
本文关键字:挂起 CPU 泛型方法 调用 反序列化 泛型类 内部 | 更新日期: 2023-09-27 17:48:49
以前有其他人遇到过这个问题吗?我有一个方法,它在泛型类内部用委托调用泛型方法。我已经将该类标记为Serializable,并且它可以毫无怨言地序列化。但是,当我尝试反序列化此类的对象时,它会挂起CPU并挂起机器。
代码示例:
public delegate T CombinationFunctionDelegate<T,U,V>(U a, V b);
[Serializable]
public class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
public SDictionary()
: base()
{
}
protected SDictionary(SerializationInfo info, StreamingContext context)
: base(info, context)
{}
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
}
public List<ListItem> ToListItems()
{
return Convert(delegate(TKey key, TValue value)
{
return new ListItem(key.ToString(), value.ToString());
});
}
public List<U> Convert<U>(CombinationFunctionDelegate<U, TKey, TValue> converterFunction)
{
List<U> res = new List<U>();
foreach (TKey key in Keys)
res.Add(converterFunction(key, this[key]));
return res;
}
}
我可以把这个类的一个实例放入ViewState中(例如),但当我再次尝试从ViewState中提取对象时,机器上的CPU会出现峰值,反序列化调用永远不会返回(即无限循环)。
当我删除ToListItems()方法时,一切都非常好用。这真的很奇怪吗,还是我只是不理解序列化?=)
这是我目前拥有的代码,哪个工作正常?
[Serializable]
public class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
public SDictionary()
: base()
{
}
protected SDictionary(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
public List<ListItem> ToListItems()
{
return this.Convert(delegate(TKey key, TValue value)
{
return new ListItem(key.ToString(), value.ToString());
});
}
public List<U> Convert<U>(CombinationFunctionDelegate<U, TKey, TValue> converterFunction)
{
List<U> res = new List<U>();
foreach (TKey key in Keys)
res.Add(converterFunction(key, this[key]));
return res;
}
}
class Program
{
static void Main(string[] args)
{
SDictionary<string, string> b = new SDictionary<string, string>();
b.Add("foo", "bar");
System.IO.MemoryStream memStream = new System.IO.MemoryStream();
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter f = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
f.Serialize(memStream, b);
memStream.Position = 0;
b = f.Deserialize(memStream) as SDictionary<string, string>;
}
}
这有帮助吗?
编辑:再次调整。
您使用的是VS2008 SP1吗?SP1存在已知问题。
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=361615
首先,Dictionary<>已经实现了ISerializable,所以不需要指定显式!
其次,您覆盖了GetObjectData(),但似乎没有调用Dictionary.GetObjectData(?因此,当您访问此时。Keys,你最终会遇到"问题"。
是的,我在这里大声思考;)
也许你可以试试这个:
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
// deserialize the dictionary first
base.GetObjectData(info, context);
// the rest of your code
// ...
}
我还没有尝试或编译过这个,但它可能是需要考虑的?
祝你好运:)
匿名方法是否引用了它所在的实例?我不能回答。
你的评论表明这是可能的。这里有一个最简单的方法:不要使用匿名方法。
public ListItem ToListItem(TKey key, TValue value)
{
return new ListItem(key.ToString(), value.ToString());
}
我可以回答的是,这个类上的方法可以根据Dictionary<T、 U>,因此当您可以针对Dictionary<T、 U>(假设C#3)
类似这样的东西(自由手代码,所以可能不是100%正确)
public static List<ListItem> ToListItems(this Dictionary<T, U> source)
{
return source
.Select(x => new ListItem(x.key.ToString(), x.value.ToString()))
.ToList();
}
public static List<V> Convert<V>
(
this Dictionary<T, U> source,
Func<T, U, V> converterFunction
)
{
return source
.Select(x => converterFunction(x.Key, x.Value))
.ToList();
}
如果有人需要,这里还有关于这个bug的知识库文章:
在运行Microsoft.NET Framework 3.5 Service Pack 1(SP1)的计算机上,您有一个序列化和反序列化泛型类的应用程序。如果泛型类至少有一个静态成员,您可能会遇到以下症状之一:
- 如果应用程序作为32位进程运行,则执行反序列化的线程可能会进入循环。因此,应用程序会出现故障,并且会消耗大量的CPU资源
- 如果应用程序作为64位进程运行,则会引发异常,并且您会收到类似于以下内容的错误消息: