简体   繁体   English

protobuf-net线程安全吗?

[英]Is protobuf-net thread safe?

I've noticed that when I use protobuf-net in a multi-threaded context it tends to fail intermittently with the following error:我注意到,当我在多线程上下文中使用 protobuf-net 时,它往往会间歇性地失败并出现以下错误:

System.TimeoutException: Timeout while inspecting metadata; this may indicate a deadlock. 
This can often be avoided by preparing necessary serializers during application initialization, rather than allowing multiple threads to perform the initial metadata inspection

However, if I lock access to the protobuf-net serializer the first time a particular type is serialized, it works without failing.但是,如果我在第一次序列化特定类型时锁定对 protobuf-net 序列化程序的访问,它就不会失败。

Is protobuf-net meant to be thread safe, or is this just a bug? protobuf-net 是线程安全的,还是这只是一个错误?

Protobuf's metadata inspection is not threadsafe. Protobuf的元数据检查不是线程安全的。 This error is "rare" but happens a lot in huge serializations that are done in parallel. 这个错误是“罕见的”,但在并行完成的大型序列化中会发生很多。 I had this exact error in my project where I serialize approximately 70 million objects. 我在我的项目中遇到了这个确切的错误,我将序列化了大约7000万个对象。 You can fix it by generating the metadata AHEAD of serialization: 您可以通过生成序列化的元数据AHEAD来修复它:

Serializer.PrepareSerializer<YourCustomType1>();
Serializer.PrepareSerializer<YourCustomType2>();

Do that code somewhere ahead of serialization, perhaps a static constructor, for each of your custom types that are serialized. 在序列化之前的某个地方执行该代码,可能是静态构造函数,用于序列化的每个自定义类型。

You can also try to increase Protobuf's metadata inspection timeout to try and aid you, but in the case of a true deadlock in the Protobuf code this really just delays your exception: 您还可以尝试增加Protobuf的元数据检查超时以尝试帮助您,但是如果Protobuf代码中存在真正的死锁,这实际上只会延迟您的异常:

// Initialize Protobuf Serializer for 5 minutes of wait in the case of long-waiting locks
RuntimeTypeModel.Default.MetadataTimeoutMilliseconds = 300000;

While Haney's answer helped me when I first encountered thread-related issues with protobuf-net, I later noticed weird behavior when multiple threads were serializing our data structure.当我第一次遇到 protobuf-net 的线程相关问题时, Haney 的回答对我有所帮助,但后来我注意到当多个线程序列化我们的数据结构时出现奇怪的行为。 To be more precise, serialization still succeeded but it was not possible to correctly deserialize the ouput afterwards (which defies the purpose).更准确地说,序列化仍然成功,但之后无法正确反序列化输出(这违背了目的)。 The deserialized objects had all members at default/uninitialized value.反序列化对象的所有成员都是默认值/未初始化值。

I ended up using SemaphoreSlim to make sure only 1 thread can access the serialization code at a time.我最终使用SemaphoreSlim来确保一次只有 1 个线程可以访问序列化代码。 With that fix, everything was behaving correctly (and I can live with the delay of waiting for the semaphore).通过该修复,一切都正常运行(我可以忍受等待信号量的延迟)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM