【问题标题】:Problems using protobuf-net RuntimeTypeModel and precompile with WPF client使用 protobuf-net RuntimeTypeModel 和使用 WPF 客户端预编译的问题
【发布时间】:2012-11-14 01:00:22
【问题描述】:

谁能解释我如何使用预编译的 protobuf-net 序列化程序集与 WCF 和客户端(不是在代码中序列化/反序列化)来加快 DTO 类型的首次使用?

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

在一个相关问题上,我在某些 DTO 中有 SolidColorBrush 类型的属性,这使得预编译器因“没有为类型定义序列化程序:System.Windows.Media.SolidColorBrush”而崩溃。 我有一些代码可以将此支持添加到 protobuf-net 模型,但是当其余的 DTO 都用例如属性装饰时,我无法理解如何应用它(到预编译器或我的代码)。 ProtoContractAttribute.

非常感谢任何帮助

【问题讨论】:

    标签: wpf wcf performance protobuf-net precompile


    【解决方案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");
    

    但是,在使用“预编译”时,我还没有添加一种机制来执行此操作——这在技术层面要复杂得多:我不能只在(比如说)属性上使用可执行方法,因为程序集是“预编译”检查的可能适用于任何 CLI(Silverlight、WinRT、.NET 1.1、CF 等)——因此,它是由非常不同的机制加载的。

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

    【讨论】:

    • 马克,感谢您的帮助。我正在尝试测试并实施您提出的建议。我特别喜欢 CompileInPlace 的想法,是的,我有数百个 DTO。等我都试过了,我会在这里跟进。
    • Marc,我在 r580 和预编译方面取得了巨大的成功,但是我刚刚安装了 r602,现在我遇到了问题。我使用 ImplicitFields.AllFields 让我的 DTO 使用最少的额外代码并且预编译运行正常,现在我在任何私有声明上都得到“非公共成员不能用于完整的 dll 编译”。有任何想法吗?谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    • 1970-01-01
    • 2013-04-25
    • 1970-01-01
    • 1970-01-01
    • 2018-02-15
    相关资源
    最近更新 更多