Ich bekomme eine Ausnahme Serialisierung Objektgraph (nicht sehr tief). Aussagekräftigen Teil davon ist, wie folgt aus:protobuf-net: Mögliche Rekursion erkannt
[ERROR] FATAL Unbehandelte Ausnahme: ProtoBuf.ProtoException: Mögliche Rekursion d etected (offset: 5-Ebene (n)): rot bei ProtoBuf.ProtoWriter.CheckRecursionStackAndPush (object) < 0x00127> bei ProtoBuf.ProtoWriter.StartSubItem (Objekt, ProtoBuf.ProtoWriter, bool) < 0x0002f>
Der graph repräsentiert sieht Datei/Verzeichnisstruktur und mein Modell (vereinfacht) wie folgt aus:
[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; }
}
Die Tiefe dieses Baumes ist in der Nähe von 10-15 Ebenen, die weniger als ProtoBuf.ProtoWriter.RecursionCheckDepth
Wert (25). (Also vielleicht ist das ein Fehler?) Die Version von Protobuf-Net ist eine kompiliert aus Kofferraum v2 (rev 491).
Eigentlich löste ich es mit der Änderung von Protobuf-net-Code. Ich habe den Wert von ProtoBuf.ProtoWriter.RecursionCheckDepth
auf 100 geändert und alles scheint in Ordnung zu sein.
Die Frage ist, ob es irgendwelche "wahre" Art und Weise zu Serialisieren solcher Art von Graphen ohne Änderung der Protobuf-Code? Ist ein solches Verhalten korrekt oder ist es ein Fehler?
Meine Plattform ist Mono-2,10-8 auf Windows 7 Professional 64-Bit-
P. S. Auch ich fand, dass, wenn ich mit thw folgenden Code deserizlie, ich parameterlosen Konstruktor PackageDirectory haben sollte, um öffentlich zu sein.
var value = new PackageDirectory();
RuntimeTypeModel.Default.Deserialize(ms, value, typeof(PackageDirectory), new SerializationContext {
Context = new DeserializationContext {
FileStream = _file,
}});
Es ist ein anderes Thema, aber es ist gut dargestellt mit vorgestellten Code. Ich denke, dass in diesem Fall der private Konstruktor deklariert werden sollte, da sich das Verhalten nun von dem für Serializer.Deserialize (...) unterscheidet.
Das Konstruktor-Problem klingt seltsam und unerwartet - wiederum müsste repro; Auf welcher Plattform läuft das? reguläre .NET? oder...?(SL und CF haben hier einige kleine Unterschiede aufgrund von Einschränkungen der Plattform) –
@MarcGravell, Sorry für unvollständige Informationen, ich habe vergessen, meine Plattform anzugeben. Es ist Mono. Ich werde eine Frage bearbeiten. – ILya
mono auf ...? Linux? iOS? Auch: welche ** genaue ** Versionsnummer verwendest du? –