Является ли Json.NET JsonSerializer потокобезопасным?
Я пытаюсь уменьшить количество мусора, создаваемого моим веб-сервисом, и я заметил, что мы создаем новый экземпляр Json.NET JsonSerializer
для каждого запроса. Это не самый легкий объект, поэтому мне интересно, могу ли я просто создать один экземпляр и повторно использовать его для всех запросов. В первую очередь это требует, чтобы он был поточным во время сериализации и десериализации.
В документации не указано, является ли оно потоковым или нет.
Проверяя код, похоже, что методы сериализации и десериализации являются потокобезопасными, если вы не изменяете никаких параметров на объекте одновременно. Тем не менее, это сложный класс, поэтому я не уверен на 100% моего анализа.
Кто-нибудь пытался повторно использовать экземпляры JsonSerializer
и работал ли он? Существуют ли какие-либо известные проблемы с повторным использованием?
Ответы
Ответ 1
Проверяя код, кажется, что методы сериализации и десериализации являются потокобезопасными, если вы не изменяете никаких параметров на объекте одновременно.
Правильно, JsonSerializer является потокобезопасным.
В процессе сериализации не используется какое-либо состояние, но если вы измените настройку на JsonSerializer, находясь в середине сериализации объекта, то они будут автоматически использоваться.
Ответ 2
В соответствии с Сравнение функций на сайте Newtonsoft это потокобезопасно, как и DataContractJsonSerializer
и JavaScriptSerializer
.
![введите описание изображения здесь]()
Ответ 3
Если вы не используете ссылки, JsonSerializer
является потокобезопасным. Однако есть несколько проблем при использовании ссылок в многопоточном контексте.
Во-первых, ошибка по умолчанию ReferenceResolver
, которая может привести к дублированию ссылочного идентификатора. См. Вопрос GitHub здесь.
Во-вторых, при повторном использовании JsonSerializer
по умолчанию ReferenceResolver
имеет значение stateful, так что если вы используете ссылки, ваши идентификаторы ссылок будут продолжать увеличиваться с каждым вызовом сериализации, который вы делаете, а не начинать с 1 для каждого. Я создал проблему GitHub для решения этой проблемы здесь.
Ответ 4
Я заметил, что мы создаем новый экземпляр Json.NET JsonSerializer
для каждого запроса. Это не самый легкий объект когда-либо...
Может быть, не "никогда", но я подозреваю, что это очень недорогой объект для создания, потому что сама библиотека делает это регулярно, например, статический и часто используемый метод JsonConvert.SerializeObject
, который определяется следующим образом:
public static string SerializeObject(object value, Type type, JsonSerializerSettings settings)
{
JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
return SerializeObjectInternal(value, type, jsonSerializer);
}
Учитывая зрелость и популярность библиотеки, я подозреваю, что если бы JsonSerializer
был даже немного дорогим в создании, были бы предприняты некоторые усилия для их кеширования в этих статических методах. Так что, хотя это безопасно для потоков, я все же думаю, что, если это не самые экстремальные обстоятельства, вы будете в порядке, создавая их по требованию.