简体   繁体   English

.NET:JsonMediaTypeFormatter线程安全吗?

[英].NET: Is JsonMediaTypeFormatter thread safe?

The following code is slow because it generates dynamic serialization classes on every run: 以下代码很慢,因为它在每次运行时都会生成动态序列化类:

var formatter = new JsonMediaTypeFormatter();
... // configure formatter

MyDocument value = new MyDocument();
HttpContent content = new ObjectContent<MyDocument>( value, formatter );
await httpClient.PutAsync( url, content );

Ideally I should cache the formatter value, however I'm using threads and the documentation says that instance members are not thread safe. 理想情况下我应该缓存formatter值,但是我正在使用线程, 文档说实例成员不是线程安全的。 This sounds like a design flaw or imprecise documentation, as the media type formatters can be used as ASP.NET content parsers (which are obviously thread-aware). 这听起来像是设计缺陷或不精确的文档,因为媒体类型格式化程序可以用作ASP.NET内容解析器 (显然是线程感知的)。 Still it doesn't preclude the possibility that ASP.NET is using locks to avoid concurrent access. 仍然不排除ASP.NET使用锁来避免并发访问的可能性。

Do you know any good source or indication that the JsonMediaTypeFormatter is actually thread-safe? 您是否知道JsonMediaTypeFormatter实际上是线程安全的任何好的来源或指示?

I believe the automatically-generated documentation just uses that common phrase for most classes. 我相信自动生成的文档只是在大多数类中使用该常用短语。

Serializers/formatters are usually designed in a way they can be reused from different threads. 序列化器/格式化程序通常以可以从不同线程重用的方式设计。 The thread-safety criteria is they don't update any instance variables in an unsafe manner. 线程安全标准是它们不以不安全的方式更新任何实例变量。 And you can always ensure it with ildasm, ilspy or any other .net decompiler tool. 您可以随时使用ildasm,ilspy或任何其他.net反编译工具来确保它。

For example, your JsonMediaTypeFormatter.WriteToStreamAsync() only reads instance properties and calls static methods. 例如,您的JsonMediaTypeFormatter.WriteToStreamAsync()仅读取实例属性并调用静态方法。 The only exception is _dataContractSerializerCache.GetOrAdd() call inside GetDataContractSerializer() (only when UseDataContractJsonSerializer is enabled), but it is also safe since _dataContractSerializerCache is a ConcurrentDictionary , hence thread-safe by design. 唯一的例外是_dataContractSerializerCache.GetOrAdd()内调用GetDataContractSerializer()仅当UseDataContractJsonSerializer启用),但它也是安全的,因为_dataContractSerializerCacheConcurrentDictionary ,因此线程安全的设计。

So there's no reason for JsonMediaTypeFormatter to be thread-unsafe. 所以没有理由让JsonMediaTypeFormatter成为线程不安全的。

PS On the other hand, I don't see how caching JsonMediaTypeFormatter will improve performance a lot, because there's no heavy work done inside the constructor, just some fields' initialization. PS另一方面,我没有看到缓存JsonMediaTypeFormatter如何提高性能,因为在构造函数中没有繁重的工作,只是一些字段的初始化。 Compared to serialization itself and network I/O overhead, it should be quite negligible. 与序列化本身和网络I / O开销相比,它应该是可以忽略不计的。

After I struggled to find what was causing performance issues in my code, I did a gist to prove where the performance issue was: 在我努力寻找导致代码性能问题的原因后,我做了一个要点,以证明性能问题在哪里:

https://gist.github.com/anonymous/6c47b4138595e13f53c162d1c69ba0ed (A copy-n-paste made the gist use the static method two times in the last tuple). https://gist.github.com/anonymous/6c47b4138595e13f53c162d1c69ba0ed (拷贝n-paste使得gist在最后一个元组中使用静态方法两次)。

The problem is in the code produced to read/write using DataContractJsonSerializer. 问题在于使用DataContractJsonSerializer生成的读/写代码。

Also, I didn't find any official documentation regarding this issue neither in Mictosoft documentation nor in the internet. 此外,我在Mictosoft文档和互联网上都没有找到任何关于此问题的官方文档。

Thanks for pointing us up in the right direction. 感谢您指引我们正确的方向。 I don't know if it's possible, but you could edit the question title and add performance issues in it. 我不知道是否可能,但您可以编辑问题标题并在其中添加性能问题。

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

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