Подтвердить что ты не робот

Является ли Json.NET JsonSerializer потокобезопасным?

Я пытаюсь уменьшить количество мусора, создаваемого моим веб-сервисом, и я заметил, что мы создаем новый экземпляр Json.NET JsonSerializer для каждого запроса. Это не самый легкий объект, поэтому мне интересно, могу ли я просто создать один экземпляр и повторно использовать его для всех запросов. В первую очередь это требует, чтобы он был поточным во время сериализации и десериализации.

В документации не указано, является ли оно потоковым или нет.

Проверяя код, похоже, что методы сериализации и десериализации являются потокобезопасными, если вы не изменяете никаких параметров на объекте одновременно. Тем не менее, это сложный класс, поэтому я не уверен на 100% моего анализа.

Кто-нибудь пытался повторно использовать экземпляры JsonSerializer и работал ли он? Существуют ли какие-либо известные проблемы с повторным использованием?

4b9b3361

Ответ 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 был даже немного дорогим в создании, были бы предприняты некоторые усилия для их кеширования в этих статических методах. Так что, хотя это безопасно для потоков, я все же думаю, что, если это не самые экстремальные обстоятельства, вы будете в порядке, создавая их по требованию.