【问题标题】:WCF: Significant Lag Returning Large Data Set over HttpBinding?WCF:通过 HttpBinding 返回大型数据集的显着滞后?
【发布时间】:2015-02-11 09:48:08
【问题描述】:

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

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

在我的联网开发机器上,此事务非常快。如果我减少查询结果(例如 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,我无法分页或异步结果。

【问题讨论】:

  • 先想一想这个问题。你到底为什么要拉下 11000 条记录?咳咳……Facebook 是否一次性拉下 10 年的墙/饲料,嘿,使用 GZip 压缩。顺便说一句,您甚至不需要使用 customBinding 来使用 GZip。您可以改用 IIS 动态压缩以获得更好的性能。
  • 这是一个文章编辑工具。用户需要在 dataGrid 中呈现给他们的所有数据。这不是 Facebook,要求完全不同……
  • 您可能会尝试流式传输响应。看看这个:msdn.microsoft.com/en-us/library/ms733742(v=vs.110).aspx
  • 唯一的“解决方案”是以更小、更高效的批次下载数据,然后连接结果(即多次调用您的服务),但最终结果仍然会相当慢。这个要求简直荒谬:没有一个理智的人会坐下来一口气编辑 1100 个项目。此外:上传数据时也会出现同样的问题。
  • 不,我明白你的意思是记录的数量。用户编辑来自世界各地的文章。文章按国家/地区定义。因此,我不能说 TOP 200,因为那时用户只会收到“阿富汗”文章。他们需要能够滚动到他们感兴趣的国家/地区,并且至少有一种错觉,即所有数据都在那里,即使它不是......

标签: c# .net wpf wcf soa


【解决方案1】:

我对该声明表示严重担忧

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

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

用户编辑来自世界各地的文章。文章是 由国家定义。因此,我不能像当时那样说 TOP 200 用户只会收到“阿富汗”的文章。他们需要能够滚动 到他们感兴趣的国家

这是解决您的问题的关键。数据可以有效地分片(甚至使用视图公开)成较小的数据集,例如可以按国家和日期进行。

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

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

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

【讨论】:

  • WCF 服务由 Windows 窗体应用托管。使用该服务的客户端应用程序是 WPF。我发布的配置来自服务 app.config。很抱歉有任何混淆。
  • 我的观点仍然成立 - winforms 是否比 WPF 更非正统。所以你是说只有windows窗体应用程序运行时服务才存在?
  • 该服务由一个 winforms 应用程序托管,所以是的。有一个启动按钮调用 host = new ServiceHost(typeof(IsesService.IsesService));主机.打开();。这是在不使用 IIS 的情况下托管 WCF 服务的常用方法...
  • 那么如果客户端调用了服务,而winforms应用恰好被关闭了怎么办?我可以向您保证,这不是托管 WCF 服务的常用方式。看看这里:msdn.microsoft.com/en-us/library/ms730158%28v=vs.110%29.aspx - winforms/wpf 明显缺席
  • @Hardgraf - 你是对的 - 在那篇文章中它确实概述了你的确切用例。我必须说我很惊讶,但我想我以前没有遇到过这种事情。
【解决方案2】:

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

您使用了 SQL 分析器,但没有提供任何与 WCF 服务、EF 等相关的分析信息,这对于解决此问题更为重要。

假设您的消息大小为 4KB,这意味着您一次通过网络传输了数十 MB,此外还使用了两端的缓冲,这对于大负载来说不是最佳选择。这些记录的默认 XML 序列化/反序列化也是一个问题,因为它很慢。使用像 EF 这样的 ORM 拉取 11K 也不是一个好主意,因为它比 ADO.NET 或 MicroORM 慢。所以你的整个架构是错误的。

我已尝试流式传输响应,但没有任何区别。

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

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

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

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

此外,每当您处理远程服务时,都应该使用 Async IO,除非您想扼杀应用的可扩展性。

【讨论】:

  • 我在我的 WCF 服务解决方案中使用 EF6 .edmx 模型。我正在使用 Linq to Entities 访问 SQL 服务器数据库(例如 var query = from a in _Context.Articles select a;)。结果返回到客户端的 ObservableCollection。 ObservableCollection = new ObservableCollection(ServiceInstance.GetAllArticles());
  • 做一个微基准测试并测量 C# 中该查询的响应时间。然后重构它以使用像 dapper 或原始 ADO.NET 这样的 MicroORM 并查看差异。如果你想要性能,永远不要使用大而臃肿的 ORM。
  • 我可以在分析器上看到查询,查询执行得非常快。我认为这是实体框架和结果集的绝对大小在瓶颈 vpn 上的组合,这正在减慢速度。也许原生 SQL 会更快,但就像您指出的那样,UI 确实需要在初始化时进行过滤,以免返回 11000 条记录。
  • 是的,查询速度很快,但 EF 在查询之上添加了更多内容。抽象是有代价的。您可以改进所有层的内容并获得一个非常快速的应用程序。您绝对应该通过提取更小的数据块来过滤、分页或无限滚动;)
  • 没错。我并不是说 EF 是唯一的问题,但是使用性能更高的 ADO.NET 可以稍微提高性能。你说得对,真正的问题是有效载荷的大小以及它是如何通过网络传输并在客户端上处理的。
猜你喜欢
  • 1970-01-01
  • 2017-01-12
  • 2019-12-28
  • 1970-01-01
  • 2012-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-08
相关资源
最近更新 更多