【发布时间】:2011-09-10 15:07:04
【问题描述】:
我有时在尝试使用 protobuf.net 反序列化对象时收到以下异常。我很惊讶,因为我从来没有超过一个线程同时反序列化同一个对象,并且 protobuf.net 源似乎没有使用任何静态对象进行反序列化。例外确实提出了一个解决方案,但我不确定如何实施,所以欢迎举个例子。
Base Exception Type:
System.TimeoutException: Timeout while inspecting metadata; this may indicate a deadlock. This can often be avoided by preparing necessary serializers during application initialization, rather than allowing multiple threads to perform the initial metadata inspection
at ProtoBuf.Meta.RuntimeTypeModel.TakeLock(Boolean& lockTaken)
at ProtoBuf.Meta.RuntimeTypeModel.FindOrAddAuto(Type type, Boolean demand, Boolean addWithContractOnly, Boolean addEvenIfAutoDisabled)
at ProtoBuf.Meta.RuntimeTypeModel.GetKey(Type type, Boolean demand, Boolean getBaseKey)
Inner Exception Type:
System.TimeoutException: Timeout while inspecting metadata; this may indicate a deadlock. This can often be avoided by preparing necessary serializers during application initialization, rather than allowing multiple threads to perform the initial metadata inspection
at ProtoBuf.Meta.RuntimeTypeModel.TakeLock(Boolean& lockTaken)
at ProtoBuf.Meta.RuntimeTypeModel.FindOrAddAuto(Type type, Boolean demand, Boolean addWithContractOnly, Boolean addEvenIfAutoDisabled)
at ProtoBuf.Meta.RuntimeTypeModel.GetKey(Type type, Boolean demand, Boolean getBaseKey)
Stack Trace:
at ProtoBuf.Meta.RuntimeTypeModel.GetKey(Type type, Boolean demand, Boolean getBaseKey)
at ProtoBuf.Meta.TypeModel.GetKey(Type& type)
at ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type)
问候, 马克
编辑添加:我这样定义我的可序列化对象:
[ProtoContract]
public class Job
{
[ProtoMember(1)]
public long JobId { get; private set; }
}
我很难在每个可序列化对象上轻松调用 PrepareSerialiser,因为我在不同的命名空间中有很多。但是考虑一下,如果要求 protobuf 在完全相同的时间反序列化两个相同类型的对象,这是它以前从未见过的类型,会发生什么?
【问题讨论】:
-
嘿,马克。如果我能可靠地重现该问题,我肯定会提供更多信息。不幸的是,这种情况发生在如此小比例 (0.01%) 的情况下,事实证明非常很难确定。我序列化的所有对象都相对较小,可能只有 10 个值类型和几个列表。我会找出可以在哪里添加 prepareSerializer 调用,如果问题仍然存在,请告诉您。
-
我很感兴趣...我将尝试浏览代码以查找可能导致此问题的任何内容(感谢包含完整的堆栈跟踪,顺便说一句 - 这很有帮助)。这……很奇怪。
-
值得补充的是,虽然我只有一个线程反序列化一个唯一的字节 [],但我可能有多达 100 个线程同时反序列化 100 个唯一的字节 []。可能是与 CPU 负载有关的问题,即开始反序列化和结束之间的时间太长?
标签: c# deadlock protobuf-net