Стабильность сериализации .NET в разных версиях платформы.

StackOverflow https://stackoverflow.com/questions/203694

Вопрос

Проект, над которым я работаю, требует сериализации структуры данных перед завершением работы и восстановления ее состояния из этих сериализованных данных при новом запуске.

В прошлом году мы работали над .NET 1.1 и столкнулись со сложной проблемой:

  • наш код работал на .NET 2.0
  • клиент обновил какое-то программное обеспечение, которое каким-то образом установило версию 1.1 по умолчанию
  • наш код работал на .NET 1.1 и не смог десериализовать сохраненное состояние.

Эта конкретная проблема была «решена» путем запрета этого конкретного обновления программного обеспечения, и теперь, когда мы ориентируемся на платформу .NET 2.0 (поэтому мы не можем работать на 1.1), она не должна быть проблемой.

Какова вероятность того, что эта сериализация может снова измениться несовместимо между 2.0 и более новыми платформами?Если мы используем <supportedVersion> чтобы исправить наш код до 2.0.50727, каковы шансы на изменения между 2.0.50727.1434 и 2.0.50727.nnnn (какая-нибудь будущая версия)?Сериализуемые структуры данных представляют собой массивы, карты, строки и т. д. из стандартных библиотек классов.

Кроме того, гарантировано ли, что платформа 2.0.50727 всегда будет установлена ​​даже после дальнейших обновлений .NET?Указатели на документацию Microsoft приветствуются.

Это было полезно?

Решение

Вероятность того, что между версиями фреймворка будут изменения, мала (но не равна нулю!).Цель состоит в том, чтобы вы могли использовать двоичную сериализацию и удаленное взаимодействие для связи между клиентом и сервером, на которых работают разные версии платформы.Несовместимость между .NET 1.x и 2.0. это ошибка для которого доступен патч.

Однако у двоичной сериализации есть и другие проблемы, особенно плохая поддержка версий сериализуемой структуры.В описанном вами случае сериализация XML является очевидным выбором:DataContractSerializer более гибок, чем XmlSerializer, если вы не возражаете против зависимости от .NET 3.x.

Вы не можете гарантировать, что .NET framework 2.0 всегда будет установлен в будущих версиях Windows.Но я уверен, что Microsoft приложит все усилия, чтобы большинство приложений .NET 2.0 работали без изменений в .NET 4.x и более поздних версиях.У меня нет никаких ссылок на это:любое такое обязательство в любом случае действительно применимо только к следующей версии Windows (Windows 7).

Другие советы

Обычное правило таково:XML-сериализация должна выдерживать новые версии платформы и, следовательно, может храниться в течение длительного времени, но двоичная сериализация не может (и, следовательно, должна быть только временной).

Какой сериализатор вы используете?Во многих отношениях сериализатор, такой как XmlSerializer или DataContractSerializer, избавляет вас от многих деталей и предоставляет более простые возможности расширения.В какой-то момент, несомненно, потребуется новая версия CLR, поэтому я не думаю, что кто-либо может дать какие-либо гарантии относительно версии 2.0.50727;Однако в краткосрочной перспективе вы должны быть в безопасности.И я надеюсь, что критических изменений будет меньше...

[обновлено следующее примечание к другому ответу]

Если вам нужен двоичный формат из соображений экономии места и производительности, другой вариант — использовать другой двоичный сериализатор.Например, protobuf-net работает со всеми вариантами .NET*, но двоичный формат (разработанный Google) совместим с кроссплатформенностью (Java, C++ и т. д.), что делает его очень переносимым, быстрым и небольшим.

*=Я не пробовал это на микрофреймворке, но все поддерживаются CF, Silverlight, Mono, .NET 2.0 и т. д.

Если совместимость вызывает беспокойство, ISerializable интерфейс может быть лекарством, которое вы ищете.Этот интерфейс дает вам больше контроля над сериализацией элементов.Для получения дополнительной информации попробуйте это статья на MSDN.

У меня есть две вещи, чтобы добавить к другим ответам...

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

Во-вторых, я считаю обязательным писать обширные модульные тесты для любых сохраненных данных.В частности, я всегда провожу два теста:

  1. Тест туда и обратно: можете ли вы сериализовать и десериализовать свои объекты и получить обратно то же самое?
  2. Тест импорта устаревших версий – убедитесь, что у вас есть версии сериализованных данных, экспортированных из каждой выпущенной версии вашего приложения.Импортируйте данные и убедитесь, что все возвращается так, как ожидалось.

Вам не обязательно использовать XML, чтобы добиться большей гибкости и управления версиями.

Я использовал библиотеку с открытым исходным кодом Саймона Хьюитта, см. Оптимизация сериализации в .NET — часть 2 вместо сериализации .NET по умолчанию.Он предлагает некоторую автоматизацию, но по сути вы можете контролировать поток сериализуемой и десериализованной информации.Для выпуска версии версия (файл) может быть сериализована первым, а во время десериализации, как интерпретируется поток информации, зависит от версии.

Это довольно просто сделать, хотя и несколько утомительно из -за явной сериализации / десериализации.

В качестве бонуса он работает в 20-40 раз быстрее и занимает меньше места для больших наборов данных (но в вашем случае это может быть неважно).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top