【问题标题】:Get a big List<T> from WCF in chunks?从 WCF 中获取一个大的 List<T> 块?
【发布时间】:2011-04-12 23:59:16
【问题描述】:

我正在尝试从 WCF 服务获取实体列表,我遇到的问题是我们在网络上有一些糟糕的延迟,因此数据需要相当长的时间才能到达我的客户端。我的想法是找到一种方法来获取前 1000 个,然后在等待下一个到达时将它们推送到 UI。

我想这就像分页,但我只想在 WCF 层中分页,而不是从数据库中一次获取一页

干杯

【问题讨论】:

    标签: c# wcf


    【解决方案1】:

    WCF 在将消息传递给更高级别之前会查看整个消息。因此,您的数据需要以完整的形式到达,而通常的 WCF 合同将不起作用。

    但是,您可以使用streaming with WCF。这允许从流中逐渐读取有效负载并传递到更高级别。为了使其正常工作,您需要:

    • 启用流式传输(在我提供的link 中)
    • 更改服务合同以提供流
    • 在服务器端,开始序列化实体并写入流,可能以 100 个块为单位。您需要自己序列化实体,尽管使用我们的 DataContractSerializer 非常简单。
    • 您需要在这 100 个实体之间提供一个分隔符,以便您的流程可以发现当前 100 的结束位置。一种可能的选择是 1 KB 的零字节。
    • 在客户端,实现异步功能。继续从缓冲区(例如 4KB)中的流中读取,直到到达分隔符。一旦命中,反序列化并引发异步事件。

    这将更复杂 WCF 直接开箱即用,但可以满足您的需求。

    【讨论】:

    • 没有链接了。我刚刚签入了 IE 6 (Work pc),我正在使用 Chrome。我有点担心是浏览器破坏了某些东西,但两者都是一样的。
    • 谢谢伊恩。事实上,我病了,还在床上,所以这一定是我的问题 :)
    • 我认为这值得一试,我会玩一下看看效果如何,理想情况下我想实现一些抽象的东西,我不需要在客户端担心这在内部是如何工作的
    • 如果您在仅公开流的地方实施流式传输,则代理需要知道。虽然您可以创建一个自定义代理来封装所有反序列化。
    【解决方案2】:

    您始终可以将服务接口拆分为两种方法。例如,而不是:

    List<T> GetItems()
    

    你可以拥有:

    int GetItemCount()
    
    List<T> GetItems(int start, int maxSize)
    

    这样你就可以手动实现分页了。

    【讨论】:

    • 在服务端“缓存”此列表的最佳方式是什么?
    • 这取决于你的持久层。例如,只要您跨请求共享会话,NHibernate 就会自动进行缓存。 (实际上它有一个两层缓存,还有很多选项)。如果您使用的是另一个框架,您应该查看他们的文档。如果您直接使用 SQL,可能是查看这些内容的好时机。
    • 我们直接使用 sql 并且切换不是一个选项,我已经知道 nhibernate 的好处,但是我们有客户强制执行的限制不使用它...
    【解决方案3】:

    最后,当我使用 tcpTransport 进行通信时,我结束了使用双工通道来做我需要的事情。

    我所做的只是将我当前的 SearchMethod 更改为返回一个大列表无效。在这个方法中,我从数据库中获取数据,将其分块并通过回调操作将其发送到客户端

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-23
      相关资源
      最近更新 更多