我正在配置一个 YamlDotNet 反序列化器,如下所示:
static IDeserializer CreateYamlDeserializer()
{
var deserializer = new DeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.WithTypeConverter(new YamlEnumMemberAttributeConverter())
.IgnoreUnmatchedProperties()
.Build();
return deserializer;
}
然后我有 3 个不同的解析器,都需要通过构造函数注入反序列化器。
将反序列化器注册为单例是否安全,或者考虑到解析器可以并行运行,每个服务都需要自己的实例(瞬态)吗?
services.AddSingleton<IDeserializer>(CreateYamlDeserializer());
// or: services.AddTransient<IDeserializer>(provider => CreateYamlDeserializer());
services.AddSingleton<YamlParserA>();
services.AddSingleton<YamlParserB>();
services.AddSingleton<YamlParserC>();
序列化器和反序列化器是线程安全的,可以(并且应该)用作单例。
@AntoineAubry 我已经开始收到几个这样的异常:
System.InvalidOperationException:'更改的操作 非并发集合必须具有独占访问权限。并发 对此集合执行了更新并破坏了其状态。这 集合的状态不再正确。'
正如 @alxmitch 在下面的问题中所述,序列化/反序列化目前不是线程安全的。
https://github.com/aaubry/YamlDotNet/issues/921
有一个 PR 可以使其线程安全:
https://github.com/aaubry/YamlDotNet/pull/920
在线程安全之前,我使用每个线程的序列化器/反序列化器
ThreadLocal<T>
。也可与 INodeDeserializer
配合使用。
private static readonly ThreadLocal<IDeserializer> Deserializer = new(() =>
new DeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.WithNodeDeserializer(inner => new ValidatingNodeDeserializer(inner), s => s.InsteadOf<ObjectNodeDeserializer>())
.Build()
);
Deserializer.Value.Deserialize<T>(inputValue);