我得到一个异常,试图序列化对象图(不是很深)。它有意义的部分是这样的:protobuf-net:检测到可能的递归
[ERROR]致命未处理的异常:ProtoBuf.ProtoException:可能 递归d etected(偏移量:5级(S)):红色在 ProtoBuf.ProtoWriter.CheckRecursionStackAndPush(对象)< 0x00127>在 ProtoBuf.ProtoWriter.StartSubItem(对象,ProtoBuf.ProtoWriter,布尔) < 0x0002f>
该图表示的文件/目录结构和我的模型(简化的)是这样的:
[ProtoContract]
[ProtoInclude(100, typeof(PackageDirectory))]
[ProtoInclude(200, typeof(PackageFile))]
public abstract class PackageMember
{
[ProtoMember(1)]
public virtual string Name { get; protected set; }
[ProtoMember(2, AsReference=true)]
public PackageDirectory ParentDirectory { get; protected set; }
}
[ProtoContract]
public class PackageDirectory : PackageMember
{
[ProtoMember(3)]
private Dictionary<string, PackageMember> _children;
public PackageDirectory()
{
_children = new Dictionary<string, PackageMember>();
}
public PackageDirectory (string name, PackageDirectory parentDirectory)
: this()
{
this.ParentDirectory = parentDirectory;
this.Name = name;
}
public void Add (PackageMember member)
{
_children.Add(member.Name, member);
}
}
[ProtoContract]
public class PackageFile : PackageMember
{
private Stream _file;
private BinaryReader _reader;
private PackageFile()
{}
public PackageFile (string name, int offset, int length, PackageDirectory directory, Stream file)
{
this.Name = name;
this.Length = length;
this.Offset = offset;
this.ParentDirectory = directory;
_file = file;
_reader = new BinaryReader(_file);
}
[OnDeserialized]
protected virtual void OnDeserialized(SerializationContext context)
{
var deserializationContext = context.Context as DeserializationContext;
if (deserializationContext != null)
{
_file = deserializationContext.FileStream;
_reader = new BinaryReader(_file);
}
}
[ProtoMember(3)]
public int Offset { get; private set; }
[ProtoMember(4)]
public int Length { get; private set; }
}
该树的深度接近10-15级,小于ProtoBuf.ProtoWriter.RecursionCheckDepth
值(25)。 (所以也许这是一个错误?) 版本的protobuf网使用是一个编译从中继v2(转491)。
其实,我解决了它与修改protobuf网络代码。我将ProtoBuf.ProtoWriter.RecursionCheckDepth
的值更改为100,一切似乎都没问题。
问题是如果有任何“真正”的方式来序列化这种类型的图,而不修改protobuf代码?这样的行为是正确的还是错误?
我的平台是单-2.10-8在Windows 7专业版64位
附:我还发现,如果我deserizlie与thw下面的代码,我应该有PackageDirectory无参数构造函数公开。
var value = new PackageDirectory();
RuntimeTypeModel.Default.Deserialize(ms, value, typeof(PackageDirectory), new SerializationContext {
Context = new DeserializationContext {
FileStream = _file,
}});
这是另一个话题,但它提供的代码很好地说明。我认为在这种情况下应该允许声明私有构造函数,因为现在行为与Serializer.Deserialize(...)的行为不同。
该构造函数的问题听起来很奇怪和意外 - 再次,将需要repro;这个运行的平台是什么?正规的.NET?要么...?(由于平台的限制,SL和CF在这里有一些细微的差别) – 2012-04-09 09:03:22
@MarcGravell,对不完整的信息抱歉,我忘了指定我的平台。它是单声道的。我会编辑一个问题。 – ILya 2012-04-09 15:51:09
单声道...? Linux呢? iOS版?另外:您使用的是哪个**确切的**版本号? – 2012-04-09 17:23:23