我正在尝试减少我的Web服务生成的垃圾量,我注意到我们正在为每个请求创建一个新的Json.NET JsonSerializer
实例。它不是有史以来最轻量级的对象,所以我想知道我是否可以创建一个单独的实例并将其重用于所有请求。首先,这要求在序列化和反序列化期间它是线程安全的。
The documentation没有说明它是否是线程安全的。
检查the code似乎序列化和反序列化方法是线程安全的,只要您不同时更改对象上的任何设置即可。但是,这是一个复杂的课程,所以我不能100%肯定我的分析。
是否有人尝试重复使用JsonSerializer
的实例并让它工作与否?重复使用是否有任何已知问题?
答案 0 :(得分:36)
检查代码看起来序列化和反序列化方法是线程安全的,只要您不同时更改对象的任何设置。
正确,JsonSerializer是线程安全的。
序列化时没有共享状态,但如果在序列化对象的过程中更改JsonSerializer的设置,则会自动使用这些设置。
答案 1 :(得分:14)
根据Newtonsoft网站上的Feature Comparison,它是线程安全的,DataContractJsonSerializer
也是如此
和JavaScriptSerializer
。
答案 2 :(得分:6)
如果您不使用引用,JsonSerializer
是线程安全的。但是,在多线程上下文中使用引用时会出现一些问题。
首先,默认ReferenceResolver
中存在一个错误,可能会导致使用重复的引用ID。请参阅GitHub问题here。
其次,当重用JsonSerializer
时,默认的ReferenceResolver
是有状态的,这样如果你使用引用,你的引用id将继续随着你所做的每个序列化调用而递增,而不是从每个序列化调用开始。我创建了一个GitHub问题来解决此问题here。
答案 3 :(得分:0)
我注意到我们正在为每个请求创建一个新的Json.NET
JsonSerializer
实例。它不是有史以来最轻的物体...
也许不是“永远”,但我怀疑它是一个非常便宜的创建对象,因为库本身是例行执行的,例如静态且经常使用的JsonConvert.SerializeObject
方法,即defined像这样:
public static string SerializeObject(object value, Type type, JsonSerializerSettings settings)
{
JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
return SerializeObjectInternal(value, type, jsonSerializer);
}
鉴于该库的成熟度和受欢迎程度,我怀疑如果JsonSerializer
的创建成本甚至更高,那么将需要付出一些努力才能将它们缓存在这些静态方法中。因此,尽管它是线程安全的,但我仍然认为,除非是最极端的情况,否则您可以按需创建它们。