WCF:在HttpBinding上返回大数据集的显着滞后?

时间:2015-02-11 09:48:09

标签: c# .net wpf wcf soa

我使用托管在简单Windows窗体应用程序中的Entity Framework 6的WCF服务。我的WPF客户端应用程序从服务中请求一个大视图(11000条记录),该视图被添加到ObservableCOllection中。客户端计算机通过WiFi连接到我们的VPN。

当我在db上运行SQL Server Profiler时,我可以看到查询本身非常快,Audit Logout持续时间很长,表明连接长时间保持打开状态,因为WCF返回数据通过Http给客户:

enter image description here

在我的联网开发机器上,此事务非常快。如果我减少了查询结果(例如SELECT TOP 200 ......),那么这个过程会大大加快,因此我知道导致这个问题的数据量很大。

这是我目前的约束力:

 <system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_IIsesService" maxBufferSize="2147483647"
             maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" useDefaultWebProxy="false" />
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://emea-diis01v:8082/" binding="basicHttpBinding"
            bindingConfiguration="BasicHttpBinding_IIsesService" contract="ServiceReference.IIsesService"
            name="BasicHttpBinding_IIsesService" />
    </client>      
</system.serviceModel>

我已尝试实施过Mtom消息传递,但这没有明显的积极影响。我已经阅读了使用GZip压缩和自定义绑定。这是最好的行动方案吗?实施文档很薄。

如果失败了,Net TCP绑定是否可能证明更有效,如果是这样,在Winforms应用程序而不是IIS中托管WCF服务时如何实现?

不幸的是,用户要求规定整个视图返回到客户端UI,我无法页面或异步结果。

2 个答案:

答案 0 :(得分:1)

我对声明非常关注

  

我有一个使用Entity Framework 6的WCF服务,托管在一个简单的   Windows窗体应用

这给我描绘了一幅非常混乱的画面。它表明你有一个&#34;主人&#34; WPF应用程序中包含服务,然后您分发了一堆WPF客户端应用程序,其中包含WCF客户端?您提供的配置示例定义了服务客户端,而不是服务主机。 WPF应用程序是非常不适合wcf服务的主机的原因有很多。

  

用户编辑来自世界各地的文章。文章是   由国家定义。因此我无法说出TOP 200   用户只会收到“阿富汗”#39;文章。他们需要能够滚动   到他们感兴趣的国家

这是解决问题的关键。数据可以有效地分片(或甚至使用视图公开)到较小的数据集中,可能以国家和日期为例。

  

如果不这样,Net TCP绑定可能会证明更多   高效,如果是这样,在托管WCF服务时如何实现   在Winforms应用程序而不是IIS?

是的! netTcpBinding是much faster而不是http。这肯定会加快速度。您可以通过Internet使用它,但请注意防火墙会阻止未打开的端口上的TCP流量。

作为WPF的wcf托管容器并不限制您选择传输绑定,但仍然是非常不正统的选择。

答案 1 :(得分:1)

  

当我在db上运行SQL Server Profiler时,我可以看到查询本身非常快

您使用的是SQL分析器,但是您还没有提供与WCF服务,EF等相关的任何分析信息,这对于排除故障更为重要。

假设您的邮件大小为4KB,这意味着您将同时通过线路传输数十MB,此外还在两端使用缓冲,这对于大型有效负载而言并非最佳。这些记录的默认XML序列化/反序列化也是一个问题,因为它很慢。使用类似EF的ORM拉11K也不是一个好主意,因为它比ADO.NET或MicroORM慢。所以你的整个架构都是错误的。

  

我试图传播回复,但没有任何区别。

对于大型消息而言,流式传输比缓冲更有效,但必须在服务器上正确实现,尤其是在客户端上才能生效。如果你以错误的方式使用流,它们可能比缓冲更慢。

但是,优化当前实现并不是正确的方法,您的实际问题是假设您需要在UI上预先提供11K记录。您应该重新考虑您的UI架构并按需提取数据。

  

不幸的是,用户要求规定整个视图返回到客户端UI,我无法页面或异步结果。

您可以使用的技术之一是无限滚动。还有更多。

此外,在处理远程服务时,您应该使用Async IO,除非您想要破坏应用程序的可伸缩性。