1 year ago
#365606
Charlicopter
protobuf-net serialize exception: "Key already in the list". Rarely thrown
It's rare, but there's an occasional error caught by the Serializer.Serialize<SaveFile>(...) catch block: "Key already in the list". That's it. Just that message.
I'm performing basic serialization and deserialization of video game save files using Protobuf-Net. The data model is relatively simple: Just some ProtoMember fields, including a dictionary and some ProtoContracted data-objects with their own ProtoMembers, including a dictionary.
public enum AchievementID : int
{
TEST,
TEST2,
TEST3,
};
public enum SlotSelect
{
None,
Slot1,
Slot2,
Slot3
}
[ProtoContract(SkipConstructor = true)]
public class GameNode_SaveState
{
[ProtoMember(1)] public float[] StateFloats_Local { get; } = new float[32];
}
[ProtoContract(SkipConstructor = true)]
public class Achievement_SaveFile
{
[ProtoMember(1)] public AchievementID ID { get; set; }
[ProtoMember(2)] public string Name { get; set; }
[ProtoMember(3)] public string Description { get; set; }
[ProtoMember(4)] public bool HasBeenAchieved { get; set; }
}
[ProtoContract]
public struct GameNode_LoadingIndex
{
[ProtoMember(1)] public int Target_TopGroup { get; set; }
[ProtoMember(2)] public int Target_SubGroup { get; set; }
[ProtoMember(3)] public int Target_LevelGroup { get; set; }
[ProtoMember(4)] public int Target_Stage { get; set; }
}
[ProtoContract]
public class SaveFile
{
[ProtoMember(1)] public uint Version { get; private set; }
[ProtoMember(2)] public SaveSlot Slot1 { get; private set; }
[ProtoMember(3)] public SaveSlot Slot2 { get; private set; }
[ProtoMember(4)] public SaveSlot Slot3 { get; private set; }
[ProtoMember(5)] public float[] Values { get; private set; }
[ProtoMember(6)] public DateTime Timestamp { get; set; }
[ProtoMember(7)] public Dictionary<AchievementID, Achievement_SaveFile> Achievements { get; private set; }
public SaveFile() { }
public SaveFile(uint version)
{
Version = version;
Timestamp = DateTime.Now;
Achievements = new Dictionary<AchievementID, Achievement_SaveFile>();
Values = new float[64];
Slot1 = new SaveSlot(SlotSelect.Slot1);
Slot2 = new SaveSlot(SlotSelect.Slot1);
Slot3 = new SaveSlot(SlotSelect.Slot1);
}
}
[ProtoContract(SkipConstructor = true)]
public class SaveSlot
{
[ProtoMember(1)] public SlotSelect SlotNumber { get; private set; }
[ProtoMember(2)] public bool IsFresh { get; set; }
[ProtoMember(3)] public GameNode_LoadingIndex SavedLoadingIndex { get; set; }
[ProtoMember(4)] public Dictionary<GameNode_LoadingIndex, GameNode_SaveState> GameNodeSaveStates { get; private set; }
[ProtoMember(5)] public float[] Values { get; private set; }
public SaveSlot(SlotSelect slotNumber)
{
SlotNumber = slotNumber;
SavedLoadingIndex = new GameNode_LoadingIndex();
GameNodeSaveStates = new Dictionary<GameNode_LoadingIndex, GameNode_SaveState>();
}
}
await Task.Run(() =>
{
Debug.Log("Saving via ProtoBuf...");
try
{
using (FileStream filestream = File.Create(filepath_local))
{
Serializer.Serialize(filestream, saveFile_outgoingCopy);
}
}
catch (Exception e)
{
Debug.LogError($"File save failed (Exception): {e.Message}");
}
});
The serialization process completes successfully about 99% of the time, but it does indeed fail from time to time.
The error is as follows:
File save failed (Exception): System.ArgumentException: Key already in the list
Parameter name: key
at System.Runtime.CompilerServices.ConditionalWeakTable`2[TKey,TValue].Add (TKey key, TValue value) [0x000a8] in <6073cf49ed704e958b8a66d540dea948>:0
at System.Buffers.TlsOverPerCoreLockedStacksArrayPool`1[T].Return (T[] array, System.Boolean clearArray) [0x00071] in <6073cf49ed704e958b8a66d540dea948>:0
at ProtoBuf.BufferPool.ReleaseBufferToPool (System.Byte[]& buffer) [0x00009] in /_/src/protobuf-net.Core/BufferPool.cs:61
at ProtoBuf.BufferPool.ResizeAndFlushLeft (System.Byte[]& buffer, System.Int32 toFitAtLeastBytes, System.Int32 copyFromIndex, System.Int32 copyBytes) [0x00040] in /_/src/protobuf-net.Core/BufferPool.cs:51
at ProtoBuf.ProtoWriter+StreamProtoWriter.TryFlushOrResize (System.Int32 required, ProtoBuf.ProtoWriter+StreamProtoWriter writer, ProtoBuf.ProtoWriter+State& state) [0x0001c] in /_/src/protobuf-net.Core/ProtoWriter.Stream.cs:118
at ProtoBuf.ProtoWriter+StreamProtoWriter.DemandSpace (System.Int32 required, ProtoBuf.ProtoWriter+StreamProtoWriter writer, ProtoBuf.ProtoWriter+State& state) [0x00012] in /_/src/protobuf-net.Core/ProtoWriter.Stream.cs:105
at ProtoBuf.ProtoWriter+StreamProtoWriter.ImplWriteVarint32 (ProtoBuf.ProtoWriter+State& state, System.UInt32 value) [0x00000] in /_/src/protobuf-net.Core/ProtoWriter.Stream.cs:274
at ProtoBuf.ProtoWriter+State.WriteHeaderCore (System.Int32 fieldNumber, ProtoBuf.WireType wireType) [0x00008] in /_/src/protobuf-net.Core/ProtoWriter.State.WriteMethods.cs:715
at ProtoBuf.ProtoWriter+State.WriteFieldHeader (System.Int32 fieldNumber, ProtoBuf.WireType wireType) [0x00043] in /_/src/protobuf-net.Core/ProtoWriter.State.WriteMethods.cs:79
at ProtoBuf.Serializers.RepeatedSerializer`2[TCollection,TItem].Write[TEnumerator] (ProtoBuf.ProtoWriter+State& state, System.Int32 fieldNumber, ProtoBuf.Serializers.SerializerFeatures category, ProtoBuf.WireType wireType, TEnumerator& values, ProtoBuf.Serializers.ISerializer`1[T] serializer) [0x00030] in /_/src/protobuf-net.Core/Serializers/RepeatedSerializer.cs:162
at ProtoBuf.Serializers.VectorSerializer`1[T].Write (ProtoBuf.ProtoWriter+State& state, System.Int32 fieldNumber, ProtoBuf.Serializers.SerializerFeatures category, ProtoBuf.WireType wireType, T[] values, ProtoBuf.Serializers.ISerializer`1[T] serializer) [0x00009] in /_/src/protobuf-net.Core/Serializers/RepeatedSerializer.cs:493
at ProtoBuf.Serializers.RepeatedSerializer`2[TCollection,TItem].WriteRepeated (ProtoBuf.ProtoWriter+State& state, System.Int32 fieldNumber, ProtoBuf.Serializers.SerializerFeatures features, TCollection values, ProtoBuf.Serializers.ISerializer`1[T] serializer) [0x0009c] in /_/src/protobuf-net.Core/Serializers/RepeatedSerializer.cs:134
at (wrapper dynamic-method) GameNode_SaveState.proto_8(ProtoBuf.ProtoWriter/State&,GameNode_SaveState)
at ProtoBuf.Internal.Serializers.SimpleCompiledSerializer`1[T].ProtoBuf.Serializers.ISerializer<T>.Write (ProtoBuf.ProtoWriter+State& state, T value) [0x00000] in /_/src/protobuf-net/Internal/Serializers/CompiledSerializer.cs:117
at ProtoBuf.ProtoWriter.WriteMessage[T] (ProtoBuf.ProtoWriter+State& state, T value, ProtoBuf.Serializers.ISerializer`1[T] serializer, ProtoBuf.PrefixStyle style, System.Boolean recursionCheck) [0x0001c] in /_/src/protobuf-net.Core/ProtoWriter.cs:258
at ProtoBuf.ProtoWriter+State.WriteAny[T] (System.Int32 fieldNumber, ProtoBuf.Serializers.SerializerFeatures features, T value, ProtoBuf.Serializers.ISerializer`1[T] serializer) [0x00077] in /_/src/protobuf-net.Core/ProtoWriter.State.WriteMethods.cs:377
at ProtoBuf.Internal.KeyValuePairSerializer`2[TKey,TValue].Write (ProtoBuf.ProtoWriter+State& state, System.Collections.Generic.KeyValuePair`2[TKey,TValue] value) [0x00040] in /_/src/protobuf-net.Core/Internal/KeyValuePairSerializer.cs:63
at ProtoBuf.ProtoWriter.WriteMessage[T] (ProtoBuf.ProtoWriter+State& state, T value, ProtoBuf.Serializers.ISerializer`1[T] serializer, ProtoBuf.PrefixStyle style, System.Boolean recursionCheck) [0x0001c] in /_/src/protobuf-net.Core/ProtoWriter.cs:258
at ProtoBuf.Serializers.MapSerializer`3[TCollection,TKey,TValue].Write[TEnumerator] (ProtoBuf.ProtoWriter+State& state, System.Int32 fieldNumber, ProtoBuf.WireType wireType, TEnumerator& enumerator, ProtoBuf.Internal.KeyValuePairSerializer`2[TKey,TValue]& pairSerializer) [0x00024] in /_/src/protobuf-net.Core/Serializers/MapSerializer.cs:88
at ProtoBuf.Serializers.DictionarySerializer`2[TKey,TValue].Write (ProtoBuf.ProtoWriter+State& state, System.Int32 fieldNumber, ProtoBuf.WireType wireType, System.Collections.Generic.Dictionary`2[TKey,TValue] values, ProtoBuf.Internal.KeyValuePairSerializer`2[TKey,TValue]& pairSerializer) [0x00008] in /_/src/protobuf-net.Core/Serializers/MapSerializer.cs:160
at ProtoBuf.Serializers.MapSerializer`3[TCollection,TKey,TValue].WriteMap (ProtoBuf.ProtoWriter+State& state, System.Int32 fieldNumber, ProtoBuf.Serializers.SerializerFeatures features, TCollection values, ProtoBuf.Serializers.SerializerFeatures keyFeatures, ProtoBuf.Serializers.SerializerFeatures valueFeatures, ProtoBuf.Serializers.ISerializer`1[T] keySerializer, ProtoBuf.Serializers.ISerializer`1[T] valueSerializer) [0x00029] in /_/src/protobuf-net.Core/Serializers/MapSerializer.cs:72
at (wrapper dynamic-method) SaveSlot.proto_3(ProtoBuf.ProtoWriter/State&,SaveSlot)
at ProtoBuf.Internal.Serializers.SimpleCompiledSerializer`1[T].ProtoBuf.Serializers.ISerializer<T>.Write (ProtoBuf.ProtoWriter+State& state, T value) [0x00000] in /_/src/protobuf-net/Internal/Serializers/CompiledSerializer.cs:117
at ProtoBuf.ProtoWriter.WriteMessage[T] (ProtoBuf.ProtoWriter+State& state, T value, ProtoBuf.Serializers.ISerializer`1[T] serializer, ProtoBuf.PrefixStyle style, System.Boolean recursionCheck) [0x0001c] in /_/src/protobuf-net.Core/ProtoWriter.cs:258
at ProtoBuf.ProtoWriter+State.WriteMessage[T] (System.Int32 fieldNumber, ProtoBuf.Serializers.SerializerFeatures features, T value, ProtoBuf.Serializers.ISerializer`1[T] serializer) [0x0001c] in /_/src/protobuf-net.Core/ProtoWriter.State.WriteMethods.cs:333
at (wrapper dynamic-method) SaveFile.proto_1(ProtoBuf.ProtoWriter/State&,SaveFile)
at ProtoBuf.Internal.Serializers.SimpleCompiledSerializer`1[T].ProtoBuf.Serializers.ISerializer<T>.Write (ProtoBuf.ProtoWriter+State& state, T value) [0x00000] in /_/src/protobuf-net/Internal/Serializers/CompiledSerializer.cs:117
at ProtoBuf.ProtoWriter+State.WriteAsRoot[T] (T value, ProtoBuf.Serializers.ISerializer`1[T] serializer) [0x00057] in /_/src/protobuf-net.Core/ProtoWriter.State.WriteMethods.cs:575
at ProtoBuf.ProtoWriter+State.SerializeRoot[T] (T value, ProtoBuf.Serializers.ISerializer`1[T] serializer) [0x00040] in /_/src/protobuf-net.Core/ProtoWriter.State.WriteMethods.cs:548
at ProtoBuf.Meta.TypeModel.SerializeImpl[T] (ProtoBuf.ProtoWriter+State& state, T value) [0x00048] in /_/src/protobuf-net.Core/Meta/TypeModel.cs:360
at ProtoBuf.Serializer.Serialize[T] (System.IO.Stream destination, T instance, System.Object userState) [0x0000d] in /_/src/protobuf-net/Serializer.Serialize.cs:32
at ProtoBuf.Serializer.Serialize[T] (System.IO.Stream destination, T instance) [0x00000] in /_/src/protobuf-net/Serializer.Serialize.cs:19
at SaveFileManager+<>c__DisplayClass31_0.<Save_Async>b__0 () [0x00033] in D:\PropLogic\Unity\ArcSine285\Assets\Systems_Game\GameData\SaveFileManager.cs:196
UnityEngine.Debug:LogError (object)
SaveFileManager/<>c__DisplayClass31_0:<Save_Async>b__0 () (at Assets/Systems_Game/GameData/SaveFileManager.cs:201)
System.Threading._ThreadPoolWaitCallback:PerformWaitCallback ()
c#
serialization
deserialization
protobuf-net
0 Answers
Your Answer