I\'m trying to reduce the amount of garbage my web service generates, and I noticed that we\'re creating a new Json.NET JsonSerializer
instance for each request
According to the Feature Comparison on the Newtonsoft site, it is thread safe, as are DataContractJsonSerializer
and JavaScriptSerializer
.
Inspecting the code it appears that the serialization and deserialization methods are threadsafe, as long as you don't change any settings on the object at the same time.
Correct, JsonSerializer is threadsafe.
No state is shared while serializing but if you change a setting on the JsonSerializer while in the middle of serializing an object then those will automatically be used.
I noticed that we're creating a new Json.NET
JsonSerializer
instance for each request. It is not the most lightweight object ever...
Maybe not "ever", but I suspect it's a very inexpensive object to create, because the library itself does this routinely, such as the static and oft-used JsonConvert.SerializeObject
method, which is defined like this:
public static string SerializeObject(object value, Type type, JsonSerializerSettings settings)
{
JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
return SerializeObjectInternal(value, type, jsonSerializer);
}
Given the maturity and popularity of the library, I suspect that if JsonSerializer
was even a little expensive to create, some effort would have been made to cache them in these static methods. So although it's thread safe, I still think that unless it's the most extreme of circumstances you're going to be fine creating them on demand.
If you don't use references, JsonSerializer
is thread-safe. There are however a few issues when using references in a multi-threaded context.
First, there is a bug in the default ReferenceResolver
that may cause duplicate reference id's to be used. See the GitHub issue here.
Secondly, when reusing a JsonSerializer
the default ReferenceResolver
is stateful so that if you use references your reference ids will continue to increment with each serialization call you make instead of starting at 1 for each. I created a GitHub issue to address this problem here.