Десериализация ссылки на объект Protobuf-net с использованием словаря: объект отслеживания ссылок изменил ссылку во время десериализации
У меня возникли некоторые проблемы при попытке сериализации / десериализации графа сложных объектов с использованием protobuf-net.
Я работаю над устаревшим приложением, и мы используем .Net Remoting для подключения клиента GUI к сервису C #. Мы наблюдаем низкую производительность с зарубежными пользователями из-за сериализованного размера наших графов объектов с использованием значений по умолчаниюBinaryFormatter
, что усугубляется ограниченной пропускной способностью между клиентом и сервером (1 Мбит / с).
В качестве быстрого выигрыша я решил собрать концепцию, чтобы увидеть, можно ли добиться какого-либо прироста производительности, используя вместо этого protobuf-net, реализовавISerializable
, Во время тестирования я столкнулся с проблемой, из-за которой ссылки на объекты не поддерживались.
Я собрал пример, который повторяет проблему. Я ожидаю, что объект вDictionary
(Items [1]) и объект B.A будут такими же, как я указалAsReference=true
вProtoMember
приписывать.
С помощьюprotobuf-net 2.0.0.619
Я вижу исключение, возникающее при десериализации (объект, отслеживаемый ссылками, изменил ссылку во время десериализации).
Если это не поддерживаемый сценарий, пожалуйста, дайте мне знать.
Контрольная работа
[Test]
public void AreObjectReferencesSameAfterDeserialization()
{
A a = new A();
B b = new B();
b.A = a;
b.Items.Add(1, a);
Assert.AreSame(a, b.A);
Assert.AreSame(b.A, b.Items[1]);
B deserializedB;
using (var stream = new MemoryStream())
{
Serializer.Serialize(stream, b);
stream.Seek(0, SeekOrigin.Begin);
deserializedB = Serializer.Deserialize<B>(stream);
}
Assert.AreSame(deserializedB.A, deserializedB.Items[1]);
}
Определения классов
[Serializable]
[ProtoContract]
public class A
{
}
[Serializable]
[ProtoContract]
public class B
{
[ProtoMember(1, AsReference = true)]
public A A { get; set; }
[ProtoMember(2, AsReference = true)]
public Dictionary<int, A> Items { get; set; }
public B()
{
Items = new Dictionary<int, A>();
}
}