简体   繁体   中英

.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. 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). Still it doesn't preclude the possibility that ASP.NET is using locks to avoid concurrent access.

Do you know any good source or indication that the JsonMediaTypeFormatter is actually thread-safe?

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.

For example, your JsonMediaTypeFormatter.WriteToStreamAsync() only reads instance properties and calls static methods. 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.

So there's no reason for JsonMediaTypeFormatter to be thread-unsafe.

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. Compared to serialization itself and network I/O overhead, it should be quite negligible.

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).

The problem is in the code produced to read/write using DataContractJsonSerializer.

Also, I didn't find any official documentation regarding this issue neither in Mictosoft documentation nor in the internet.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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