aaubry / YamlDotNet

YamlDotNet is a .NET library for YAML
MIT License
2.48k stars 466 forks source link

Serialization / deserialization is not thread safe #921

Open alxmitch opened 3 months ago

alxmitch commented 3 months ago

Describe the bug Concurrently deserializing or serializing the same type from multiple threads can fail. Example stack trace:

Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct.

   at System.ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported()
   at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
   at System.Collections.Generic.Dictionary`2.set_Item(TKey key, TValue value)
   at YamlDotNet.Serialization.ObjectFactories.DefaultObjectFactory.GetStateMethods(Type attributeType, Type valueType)
   at YamlDotNet.Serialization.ObjectFactories.DefaultObjectFactory.ExecuteState(Type attributeType, Object value)
   at YamlDotNet.Serialization.ObjectFactories.DefaultObjectFactory.ExecuteOnDeserializing(Object value)
   at YamlDotNet.Serialization.NodeDeserializers.ObjectNodeDeserializer.Deserialize(IParser parser, Type expectedType, Func`3 nestedObjectDeserializer, Object& value)
   at YamlDotNet.Serialization.ValueDeserializers.NodeValueDeserializer.DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer)

To Reproduce Serialize / deserialize objects of the same type from multiple threads using the same Serializer / Deserializer See https://github.com/kubernetes-client/csharp/issues/1537

alxmitch commented 3 months ago

https://github.com/aaubry/YamlDotNet/pull/920

filzrev commented 3 months ago

Add related discussion link (#844)

Currently I'm using the ThreadLocal<ISerializer> workaround though. I'd appreciate if a thread-safe implementation is also supported.