Runtime: Вопрос: поддержка сериализации с версии .Net Core 1.0

Созданный на 1 мар. 2016  ·  38Комментарии  ·  Источник: dotnet/runtime

Привет всем,
Я слышал о прекращении поддержки сериализации в .Net Core 1.0, поскольку это нецелесообразно для кроссплатформенности. (Перефразируя по памяти) Что это означает на практике? Будут ли мои кодовые базы, использующие методы Serialize и Deserialize BinaryFormatter, полностью устаревшими, и мне придется преобразовать мою кодовую базу, скажем, protobuf-net? Или я неправильно понял?
Благодаря,
-Сэм

area-Serialization question

Самый полезный комментарий

Вы хотите, чтобы люди действительно использовали .NET Core, или это просто пустая трата времени, как Silverlight? Если вы хотите, чтобы люди действительно использовали .NET Core, заставьте его работать. Если людям нужна сериализация, создайте ее - никаких разговоров! Это люди, которые действительно используют ваш продукт, и их мнение намного дороже, чем коллективная мудрость каждого сотрудника Microsoft. Видите ли, эти люди, в отличие от Microsoft, на самом деле создают критически важные вещи на .NET, и если вы хотите, чтобы .NET Core был чем-то вроде, вы должны перестать нарушать его полезность. Никто не просил вас отказаться от .NET, чтобы полностью переписать, вы могли бы просто портировать всю платформу .NET со временем. Вы бы уже сделали это.

Все 38 Комментарий

Привет @joshfree , да, к сожалению, это был документ, который вызвал путаницу. Из предложенных там предложений JSON.NET выполняет сериализацию json, protobuf-net выполняет двоичную сериализацию, а datacontractserializer выполняет сериализацию xml. Проблема в том, что я хочу выполнить двоичную сериализацию. Хотя protobuf-net - отличная библиотека, она ограничена. Из репозитория Protobuf-nets поддерживаются следующие типы:
пользовательские классы, которые:
помечены как данные-контракт
иметь конструктор без параметров
для Silverlight: общедоступны
много общих примитивов и т. д.
одномерные массивы: T []
Список / IList
Словарь / IDictionary
любой тип, который реализует IEnumerable и имеет метод Add (T)
В прошлом это было нормально, поскольку двоичный форматтер всегда был там, но теперь это не так? Какой рекомендуемый способ двоичной сериализации неподдерживаемых типов с помощью protobuf-net? Сами построить?
Я все еще новичок во всех этих технологиях, поэтому я могу полностью упустить суть.

Кроме того, ни один из них не может надежно сериализовать исключения (и сохранить все соответствующие данные), если это необходимо, например, в распределенных вычислениях (Azure ...).

Точка @cdrnet - большой

Привет, @SamuelCox , как указано в руководстве по портированию @joshfree , мы (команда сериализации) не планируем переносить двоичный сериализатор в .NET Core. Без удаленного взаимодействия .NET и концепции AppDomain в .NET Core двоичный сериализатор гораздо менее полезен. Обратите внимание на другие сериализаторы в .NET Core, такие как DataContractSerializer (DCS), DataContractJsonSerializer (DCJS) и XmlSerializer, которые поддерживаются и будут поддерживаться в .NET Core. Конечно, вы также можете рассмотреть сторонние сериализаторы, построенные на .NET Core. Может быть, мне стоит задать вопрос - вы особенно ищете сериализатор с двоичной сериализованной полезной нагрузкой (если да, почему), или вы просто ищете сериализатор, который может сериализовать / десериализовать типы, которые вам нужны? Мы очень старались поддерживать сериализацию большинства типов .NET с помощью DCS, DCJS и XmlSerializer. Не стесняйтесь сообщить нам, если у вас возникнут какие-либо проблемы, связанные с тем, что эти сериализаторы вам не подходят.

@cdrnet и @ RichiCoder1 , спасибо за ваш отзыв. Была открытая проблема dotnet / coreclr # 2715 для обсуждения сериализации исключения. Пожалуйста, оставьте здесь свой отзыв. Я согласен, что важно иметь возможность сериализовать исключения в распределенной системе. В настоящее время без ISerializable в .NET Core мы просто не можем сериализовать исключения, как мы это делаем в полной платформе .NET.

Привет @zhenlan , мне, возможно, следовало упомянуть изначально, основная причина, по которой я хочу, чтобы двоичный форматировщик, - это (де) сериализация исключений и пользовательских классов, содержащих исключения.

Основной вариант использования - это распределенные системы, сериализующие некоторый объект в байтовый массив, чтобы я мог отправить его по tcp / ip. Я понимаю, что, вероятно, более распространено сериализовать объект в JSON через JSON.NET, например, преобразовать эту строку в массив байтов, отправить его через tcp / ip и отменить весь процесс один раз на другом конце. Но это намного больше, чем просто сериализация в массив байтов и десериализация из массива байтов в нужный объект.

Спасибо @SamuelCox за разъяснения. Думаю, теперь я понимаю ваше беспокойство. Бинарная сериализация - это близкая система. Я бы порекомендовал вам рассмотреть другие более открытые стандартные сериализации, такие как Xml или JSON. Возможно, вам это не понадобится сегодня, но это дает вам больше гибкости на случай, если вам понадобится поддержка сериализации между разными платформами или с разными языками программирования / сценариями в будущем. Не уверен, насколько велики будут ваши данные, но если размер полезной нагрузки действительно вызывает беспокойство, вы можете рассмотреть возможность сжатия данных, которое в настоящее время является встроенной функцией для многих серверов.

Я больше думал о накладных расходах, чем о чем-либо другом. Похоже, много потраченных впустую операций по сравнению с сериализацией и десериализацией прямо из объектов в двоичные и обратно. Думаю, я счастлив закрыть это сейчас, поскольку я, по крайней мере, получил разъяснения. Я все еще думаю, что здесь открывается разрыв между 4.6 и ядром 1.0, но я понимаю, почему.

Немного поздно к разговору, но вот мои два цента:

Я думаю, было бы ошибкой полагать, что полезность BinaryFormatter ограничена удаленным взаимодействием .NET и доменами приложений. Что отличает (устаревший) BinaryFormatter от его новых аналогов, так это его абсолютная способность сериализации более экзотических объектов .NET, включая замыкания, подтипы и циклические графы. Ни один из других сериализаторов, перечисленных в текущем потоке, не способен на все это. Неслучайно многие передовые распределенные фреймворки, включая проекты Microsoft, такие как Prajna и Mobius (также известные как SparkCLR), полагаются на BinaryFormatter в своей работе. Это не эксклюзивно для мира .NET: Spark использует старый и медленный двоичный сериализатор Java для сериализации замыканий.

Существуют и другие сериализаторы (не в двоичном формате), которые воспроизводят возможности BinaryFormatter, включая нашу собственную библиотеку FsPickler, используемую фреймворком mbrace. Однако CoreCLR отказался от многих ключевых API-интерфейсов, поскольку я считаю, что перенос библиотеки на CoreCLR является непрактичным делом.

С точки зрения бизнеса было бы здорово, если бы CoreCLR стал жизнеспособным кроссплатформенным конкурентом JVM в области распределенных вычислений / больших данных. Этого не может произойти без платформы, предлагающей надежную поддержку сериализации для POCO и замыканий (двоичных или иных).

Вы хотите, чтобы люди действительно использовали .NET Core, или это просто пустая трата времени, как Silverlight? Если вы хотите, чтобы люди действительно использовали .NET Core, заставьте его работать. Если людям нужна сериализация, создайте ее - никаких разговоров! Это люди, которые действительно используют ваш продукт, и их мнение намного дороже, чем коллективная мудрость каждого сотрудника Microsoft. Видите ли, эти люди, в отличие от Microsoft, на самом деле создают критически важные вещи на .NET, и если вы хотите, чтобы .NET Core был чем-то вроде, вы должны перестать нарушать его полезность. Никто не просил вас отказаться от .NET, чтобы полностью переписать, вы могли бы просто портировать всю платформу .NET со временем. Вы бы уже сделали это.

fwiw, CSLA .NET полагается на сериализацию с полной точностью, потому что она основана на концепции мобильных объектов.

Когда появился Silverlight и не имел BinaryFormatter или NetDataContractSerializer, _и_ были все эти неприятные ограничения отражения, мы закончили реализацию нашего собственного сериализатора, который использует минимальное отражение и не полагается на BF или NDCS.

В мире после Silverlight проблема остается, потому что BF / NDCS надежно недоступны в UWP, WinRT, .NET Core и т. Д.

Итак, я думаю, что есть аргумент, что сериализатор полной верности _должен_ существовать, но он действительно полезен (по крайней мере, imo), если он существует во всех различных воплощениях .NET.

@rockfordlhotka @opinionmachine @eiriktsarpalis Рад слышать, что больше людей чувствуют то же самое, хотя я считаю, что было бы более продуктивно, если бы это было сказано немного более вежливо @opinionmachine , но каждый сам за себя. Поскольку этот вопрос закрыт, я полагаю, что команда corefx больше не отслеживает его. Я бы посоветовал вам исправить свои опасения по поводу dotnet / coreclr # 2715, как упоминалось @forki

Я должен согласиться, что отказ от сериализации (как и от доменов приложений) был ужасной идеей. Не думаю, что это решение было хорошо продуманным.

Однако что меня действительно вдохновляет, так это то, что MS не выпустила код, необходимый для поддержки доменов приложений и т. Д., И предоставила сообществу делать с ним то, что они хотят.

Учитывая, что coreclr должен быть «серверной» версией .net, многие серверные функции были оставлены без внимания.

Показательный пример: было решено исключить StackTrace / StackFrame из corefx, потому что он «неправильно использовался» некоторыми разработчиками и потому, что он использовался редко (согласно MS). Я считаю, что они опомнились на этом (после тонны негативной реакции), но я имею в виду на самом деле? Кто об этом думает?

Как бы то ни было, я действительно доволен ядром .net и считаю, что это большой шаг вперед для .net, блестящие улучшения производительности, он по-прежнему имеет почти все функции, которые меня волнуют, и это кроссплатформенность. Это действительно единственная проблема, с которой я столкнулся. Отказ от функций там, где это необходимо, имеет большое значение, просто посмотрите, насколько успешным был его минималистичный подход. Не то чтобы я говорил, что .net должен быть настолько минималистичным, как и есть, это было бы смешно, я лично не согласен с минималистичным дизайном, НО я пытаюсь сказать, что MS не следует ругать за отказ от определенных функций.

@SamuelCox , спасибо! :-)

И, повторюсь, API отсутствуют в .NET Core по многим причинам. Некоторые из этих пробелов можно легко исправить (и мы их исправляем); некоторые исправить труднее. Но мы хотим услышать от вас о проблемах, с которыми вы сталкиваетесь (например, весь этот набор потоков о сериализации), и мы хотим найти способ разблокировать ваши сценарии.

Двоичная сериализация произвольных графов объектов в разных версиях единой платформы затруднена; в разных фреймворках еще сложнее. И под словом «тяжелый» я не имею в виду, что нам сложно выполнять эту работу. Я имею в виду, что это имеет довольно далеко идущие последствия для других целей платформы (целей, которые, я думаю, мы все разделяем): безопасность, производительность, надежность.

Json.NET + TypeNameHandling.All + PreserveReferencesHandling.All + MemberSerialization.Fields поможет вам практически полностью. Однако FormatterServices.GetUninitializedObject отсутствует, поэтому конструктор должен быть доступен.

Нет FormatterServices.GetUninitializedObject

Я думаю, это основная проблема - внешние фреймворки сериализации, основанные на отражении, могут помочь вам далеко, но этот конкретный API должен быть там, чтобы эти фреймворки можно было писать. Я рекомендую команде CoreCLR снова добавить этот API.

В какой-то момент сообществу .NET (коммерческому или иному) придется перестать полагаться на то, что Microsoft все время держит его за руку. Если для этого существует такое огромное требование, и уже довольно давно известно, что он не будет доступен, то почему не было никакой активности сообщества по предоставлению альтернативы? Json.NET - это альтернатива сообщества, и мы постоянно ее используем. Черт возьми, исходный код даже доступен в справочнике

Кажется, это работает для других платформ, и я уверен, что он отлично работает на .NET ... как я это вижу, это отличная возможность для создания проекта (который, кажется, есть спрос) и получить на раннем этапе заполнения этой пустоты альтернативой (ами) сообщества

@thecodejunkie мы бы хотели, но нам все равно нужно, чтобы среда выполнения предоставляла соответствующие API, чтобы это произошло.

К вашему сведению: это работает на .NET Core: Type appDomainType = Type.GetType("System.AppDomain"); . И да, это позволяет вам многое делать ....

Просто чтобы сказать, что мы улучшили скорость отклика нашего внешнего сервера на 30%, уменьшили с 12 ядер при максимальной нагрузке до 2 ядер при максимальной нагрузке, уменьшили размер кэша Redis с 1,7 ГБ до 350 МБ, в целом уменьшили наш хостинг Azure на 20% (бит более реально)

Вы догадались, что это BinaryFormatter!

Использовали netdatacontractserializer

Я пришел сюда в поисках ответов на то, что .Net 4.6.1 намного медленнее с BinaryFormatter.

Насколько я понимаю, эти API вернутся (сериализация). Хотя это не идеально и имеет некоторые проблемы с хрупкостью, это, по крайней мере, должно позволить существующему коду продолжать работу.

также имеет смысл разработать еще один простой сериализатор объектов для базовой платформы, который также является легким, но более устойчивым к кросс-машинным и потенциально кросс-версиям.

Помимо хрупкости, существуют также проблемы с безопасностью.

@blowdart WRT security, вы имеете в виду такие вещи, как это https://blog.scrt.ch/2016/05/12/net-serialiception/?

Ага, вот в чем дело. Любой формат сериализации, который включает тип внутри себя, опасен, как это выясняет в этом году Java. Я был невероятно счастлив, когда мы отказались от двоичной сериализации, потому что мы удалили целый класс уязвимостей.

@migueldeicaza @blowdart @SamuelCox
Сериализаторы нужны не только для отправки, но даже в процессе.
Бинарные сериализаторы, если все сделано правильно, превосходят всю кучу собственных объектов в целом, когда дело доходит до хранения десятков миллионов объектов в процессе.
Посмотри это:
https://www.infoq.com/articles/Big-Memory-Part-2

API-интерфейсы сериализации абсолютно необходимы для разумного кластерного программирования.
Крайне неудобно телепортировать экземпляры объектов CLR -> text -> CLR, это огромные накладные расходы.
Может быть, исключить BinaryFormatter не будет ошибкой, так как он ОЧЕНЬ медленный, а датаграммы огромные, но
Это был единственный сериализатор на рынке, помимо NFX.Slim, который поддерживал полную семантику сериализации CLR.
См. Подробные таблицы скорости и размера:
http://aumcode.github.io/serbench/

ISerializable с семейством [OnSer / Deser] ДЕЙСТВИТЕЛЬНО имеет смысл для телепортации внутри платформы.
Это не обязательно, как в старом NET. Почему бы не оставить его себе.
По крайней мере, поддержать его в сложных коллекциях (например, Dictionary), это совсем несложно.

Заставить всех использовать JSON - абсолютно плохая идея, поскольку он в разы медленнее двоичного сериализатора (не BinaryFormatter).
Похоже, что все создают приложения, похожие на Twitter, без бизнес-логики?

У @itadapter есть одна

@ RichiCoder1
Да, конечно. Как видно из диаграмм ниже, то есть JIL является самым быстрым сериализатором JSON, однако ни один из текстовых сериализаторов не может касаться двоичных. Protobuf очень быстр за счет его неспособности поддерживать истинный полиморфизм и сложные графы.

Все, что я говорю:

  • Двоичные сериализаторы всегда более эффективны для объектов бизнес-домена, особенно когда у вас много числовых данных.
  • Сериализаторы, как правило, необходимы НЕ ТОЛЬКО для перемещения данных между системами, но даже внутри процесса, как показывает подход Big Memory. Это нетипичный подход, но он имеет практический смысл (например, кеширование и обход социального графа в памяти).
  • «Телепортация» - это техника, похожая на MS Remoting, которая, честно говоря, была неудачной. В целом удаленное взаимодействие, если все сделано правильно (без ужасных сложностей), ОЧЕНЬ ОЧЕНЬ полезно в кластерных системах. Мы используем этот подход все время, и программирование НАМНОГО проще с собственными объектами - когда вы можете взять объекты DOMAIN и просто отправить их в другой метод как есть, будь то на этой или соседней машине в стойке.

Тесты "Типичного человека", показывающие популярные сериализаторы:
http://aumcode.github.io/serbench/Specimens_Typical_Person/web/overview-charts.htm

На всякий случай, если кто-то в этом потоке не знает, двоичный сериализатор, включая ISerializable и т. Д., Был доступен в corefx
https://github.com/dotnet/corefx/tree/master/src/System.Runtime.Serialization.Formatters

@zhenlan Я полагаю, это часть работы .NetStandard2.0?

@ RichiCoder1 Да, правильно.

@zhenlan молодец !

@zhenlan Я не могу найти атрибут Serializable, доступный в предварительной версии Standard. Я просто скучаю по нему?

@justinhelgerson он должен быть там.

Вы установили 2.0 Preview1 SDK, как описано в сообщении в блоге ?

После создания проекта .NET Core не могли бы вы убедиться, что в файле .csproj есть <TargetFramework>netstandard2.0</TargetFramework> если вы создали библиотеку классов, или <TargetFramework>netcoreapp2.0</TargetFramework> если вы создали консольное приложение?

Кстати, поскольку многие люди в этом потоке заинтересованы в двоичном сериализаторе, вас может заинтересовать обсуждение в dotnet / corefx # 19119, которое касается масштабирования [Serializable] для .NET Core 2.0. Пожалуйста, дайте нам знать там, если у вас есть какие-либо отзывы.

@zhenlan Спасибо за быстрый ответ. Я установил предварительную версию через NuGet, но я не обновлял файл .csproj вручную. Это сработало! Я прочитаю об обратном масштабировании и предоставлю информацию, если это повлияет на наш вариант использования.

@justinhelgerson , изменений масштабирования нет в Preview 1 (мы все еще работаем над ними!), но вскоре вы сможете опробовать их с ежедневными сборками или будущими превью.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги