使用protobuf-net RuntimeTypeModel和预编译与WPF客户端的问题

时间:2012-11-14 01:00:23

标签: wpf wcf performance protobuf-net precompile

任何人都可以了解如何将预编译的protobuf-net序列化程序组件与WCF和客户端一起使用(而不是在代码中序列化/反序列化)以加速首次使用DTO类型?

我通过使用protobuf-net与datacontractserializer在我的大型WCF / WPF应用程序中获得了很多性能提升。但是,即使我可以从我的DTO预编译序列化程序集,我也无法使WCF或它的WPF客户端使用它。对于涉及新DTO的该过程的任何第一次调用,Web服务进程总是花费很长时间,可能是为了动态生成序列化程序集。 如何指示WCF服务器和/或WPF客户端使用我生成的程序集?

在一个相关的问题上,我在某些DTO中有类型为SolidColorBrush的属性,这使预编译器失败,“没有为类型定义序列化器:System.Windows.Media.SolidColorBrush”。 我有一些代码可以将这种支持添加到protobuf-net模型中,但我无法理解如何应用它(对于预编译器或我的代码),当DTO的其余部分用例如attibutes进行修饰时,例如ProtoContractAttribute。

任何帮助非常感谢

1 个答案:

答案 0 :(得分:2)

目前,让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");

但是,我在使用“预编译”时还没有添加一个机制来实现这一点 - 在技术层面上它更加棘手:我不能只在一个属性上使用可执行方法,因为程序集正在“预编译”检查可以用于任何CLI(Silverlight,WinRT,.NET 1.1,CF等) - 因此,它由非常不同的机制加载。

我首选的方法是:不要将其公开为System.Windows.Media.Color - 编写代表数据的自己的DTO类(而不是最终实现),并在它们之间进行映射。或者,也可以通过配置模型然后调用RuntimeTypeModel.Default.Compile(string,string)RuntimeTypeModel.Default.Compile(CompilerOptions)来编写自己的实用程序控制台exe,其行为类似于“预编译”。