处理大型对象的WCF服务

时间:2010-07-07 08:37:03

标签: wcf

将WCF用作在远程PC之间执行RPC的方法,您可以很好地将对象作为方法参数发送。这很容易编码,但意味着每当对象发生变化时,您发送整个内容,并且还可能意味着接收器必须具有额外的逻辑才能仅对更改的字段进行操作。或者,您可以拥有一个类,该对象的每个属性都有一个方法。如果您有一个大类并且通常只更改一个属性,这种细粒度的方法对性能很有帮助。但是要编写的代码要多得多,并且每次对象获得另一个属性时都必须维护它。

是否有更好的方法可以避免为每个属性编写一堆复制粘贴方法,但是只发送实际更改的属性?我们可以从类/接口或其他东西自动生成WCF服务方法吗?

例如说我们有(伪)类,目标是两个应用程序想要保持同步的人(我添加一个复杂的属性List,使它更像现实生活):

class Pet
{
 String name;
 AnimalType type;
}

class Person
{
 int age;
 float height;
 string name;
 List<Pet> pets
}

3 个答案:

答案 0 :(得分:1)

WCF本身并不这样做。有许多方法可以找出变化,但在大多数情况下,开发人员都有责任。

唯一可以找到的预定义解决方案是ADO.NET DataServices。这实际上是来自Microsoft的Entity Framework Datacontext的RESTful WCF服务包装器。说实话,你实际上不仅可以使用EF。在客户端,您将获得跟踪更改的上下文。提交更改时,客户端仅发送具体更改。但这限制了您对HTTP传输和XML或JSON序列化的影响,这确实会影响大对象的性能。

当您向服务器发送包含某些元数据的命令时,也可能存在某种事件驱动的解决方案。

答案 1 :(得分:1)

然而,你这样做会产生开销。由您决定哪种开销最容易被您接受。可能的方法:

  1. 忽略此问题并始终发送完整实体。这里的开销是发送的大量数据。
  2. 使用ADO.NET数据服务。这里的开销是数据上下文,更改跟踪以及所有这些的一般“chattiness”。
  3. 重新设计合同以减少传递的数据量。这里的开销是服务接口的额外复杂性。
  4. 选项3的示例:

    class Person {
        string Name;
        PersonalData PersonalData;
        MedicalData MedicalData;
        List<Pet> Pets;
    }
    
    class PersonalData {
        int Age;
        string SSN;
    }
    
    class MedicalData {
        float Weight;
        float Height;
    }
    
    class Pet {
        string Name;
        AnimalType Type;
    }
    
    interface IPerson {
        void Update(Person data, bool includePersonalData, bool includeMedicalData, bool includePets);
    }
    

    在客户端代码中,如果您不想更新医疗数据,则可以将false传递给update方法,而不必在数据中实例化MedicalData对象。这减少了网络流量,因为InfoSet中的相应元素将丢失。

答案 2 :(得分:1)

解决方案实际上取决于您的绑定约束。如果您被迫使用basicHttp绑定,那么ADO.Net DataServices可能是Pavel和Christian所说的最佳方法。但是,如果NetTcp和其他更复杂的绑定(WS *)可用,您可以查看带有序交付的可靠消息传递。您可以将响应细分为较小的块,并将它们放回到另一端。另请参阅Streamed vs. Buffered转移。当然,这需要比ADO.Net DataServices更多的工作,但这使它更有趣,非?

另外,请记住合同首次开发。在Web服务中使用参数化方法将限制您的行动,您想要进行的任何更改都将强制使用新版本,即使是任何微小的更改(例如,返回的其他字段)。