Проблемы с использованием protobuf-net RuntimeTypeModel и предварительной компиляции с клиентом WPF

Может ли кто-нибудь пролить свет на то, как я могу использовать предварительно скомпилированную сборку сериализатора protobuf-net с WCF и клиентом (не для сериализации / десериализации в коде), чтобы ускорить первое использование типа DTO?

Мне удалось значительно улучшить производительность моего большого приложения WCF / WPF, используя protobuf-net по сравнению с сериализатором контрактов данных. Однако, несмотря на то, что я могу предварительно скомпилировать сборку сериализации из моего DTO, я не могу заставить WCF или клиент WPF использовать ее. Процесс веб-службы всегда занимает много времени для любого первого вызова из этого процесса, включающего новый DTO, предположительно для генерации сборки сериализации на лету. Как я могу указать серверу WCF и / или клиенту WPF использовать мою сгенерированную сборку?

Что касается связанной проблемы, у меня есть свойства типа SolidColorBrush в некоторых DTO, и это заставляет прекомпилятор отказываться от «Нет сериализатора, определенного для типа: System.Windows.Media.SolidColorBrush». У меня есть код для добавления этой поддержки в модель protobuf-net, но я не могу понять, как ее применить (к прекомпилятору или моему коду), когда остальная часть DTO украшена атрибутами, например. ProtoContractAttribute.

Любая помощь очень ценится


person Simon Evans    schedule 14.11.2012    source источник


Ответы (1)


На данный момент единственный способ заставить WCF использовать предварительно скомпилированную модель - это настроить WCF вручную с помощью кода, в частности, вручную добавить ProtoOperationBehavior и указать модель:

var behavior = new ProtoOperationBehavior();
behavior.Model = new MyPrecompiledSerializer();

Признаюсь, у меня нет полного примера выполнения этого с помощью WCF. Я подозреваю, что в новом выпуске мне будет проще настроить ProtoBehaviorExtension и / или ProtoBehaviorAttribute, чтобы вы могли указать пользовательский тип сериализатора через конфигурацию, но этого кода сегодня не существует.

Между тем, если проблема заключается в небольшой задержке первой операции, вы также можете добавить несколько типов, которые вам нужны, явно в соответствии с моделью по умолчанию и скомпилировать ее:

RuntimeTypeModel.Default.Add(typeof(Foo), true);
RuntimeTypeModel.Default.Add(typeof(Bar), true);
RuntimeTypeModel.Default.CompileInPlace();

при этом сказано: компиляция не ужасно медленная - я был бы немного удивлен, если бы она вызывала заметную задержку, если только ваша модель не действительно сложная (сотни типов) . Возможно ли, что задержка связана только с накладными расходами WCF, сети, TCP и т. Д.?


Что касается SolidBrush, и косвенно: Color - их можно настроить во время выполнения:

RuntimeTypeModel.Default.Add(typeof(System.Windows.Media.Color), false)
    .Add("R", "G", "B", "A");
RuntimeTypeModel.Default.Add(typeof(System.Windows.Media.SolidColorBrush), false)
    .Add("Color");

Однако я еще не добавил механизм для этого при использовании "прекомпиляции" - это намного сложнее на техническом уровне: я не могу просто использовать исполняемый метод (скажем) для атрибута, потому что сборка проверяется " precompile »может быть для любого CLI (Silverlight, WinRT, .NET 1.1, CF и т. д.) - и поэтому он загружается с помощью самых разных механизмов.

Я предпочитаю такой подход: не отображать его как System.Windows.Media.Color - написать свой собственный класс DTO, представляющий данные (а не окончательную реализацию), и сопоставить их. В качестве альтернативы также можно написать свою собственную служебную консоль exe, которая действует как «предварительная компиляция», настроив модель и вызвав RuntimeTypeModel.Default.Compile(string,string) или RuntimeTypeModel.Default.Compile(CompilerOptions).

person Marc Gravell    schedule 14.11.2012
comment
Марк, спасибо за помощь. Я пытаюсь проверить и реализовать сделанные вами предложения. Мне особенно нравится идея CompileInPlace, и да, у меня есть сотни DTO. Я буду следить здесь, когда все это опробую. - person Simon Evans; 15.11.2012
comment
Марк, у меня был большой успех с r580 и предварительной компиляцией, однако я только что установил r602, и теперь у меня проблема. Я использую ImplicitFields.AllFields, чтобы мой DTO работал с минимальным дополнительным кодом, и предварительная компиляция прошла нормально, теперь я получаю, что непубличный член не может использоваться с полной компиляцией dll в любом частном объявлении. Любые идеи? Спасибо - person Simon Evans; 19.11.2012