简体   繁体   English

WCF:显着滞后通过HttpBinding返回大数据集吗?

[英]WCF: Significant Lag Returning Large Data Set over HttpBinding?

I have a WCF service using Entity Framework 6 hosted in a simple Windows Forms app. 我有一个使用Entity Framework 6的WCF服务,该服务托管在一个简单的Windows Forms应用程序中。 My WPF client app requests a large view (11000 records) from the service which is added to an ObservableCOllection. 我的WPF客户端应用程序从服务中请求一个大视图(11000条记录),该服务已添加到ObservableCOllection。 The client machine is connected to our VPN over WiFi. 客户端计算机通过WiFi连接到我们的VPN。

When I run SQL Server Profiler on the db I can see that the query itself is very fast however, the Audit Logout duration is long, suggesting that the connection is staying open for a long time as WCF returns the data to the client over Http: 当我在数据库上运行SQL Server Profiler时,我可以看到查询本身非常快,但是, Audit Logout持续时间很长,这表明连接保持打开状态很长时间,因为WCF通过Http将数据返回给客户端:

在此处输入图片说明

When on my networked Dev machine, this transaction is very fast. 在我的联网Dev机器上时,此事务非常快。 If I reduce the query results (eg SELECT TOP 200...) the process speeds up considerably therefore I know it is the sheer volume of data causing the issue. 如果我减少查询结果(例如SELECT TOP 200 ...),则该过程将大大加快速度,因此,我知道是导致问题的庞大数据量。

Here is my current binding: 这是我当前的绑定:

 <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>

I have tried implemented Mtom messaging but this had no noticeable positive effect. 我已经尝试过实施Mtom消息传递,但这没有明显的积极作用。 I have read around using GZip compression with a custom binding. 我已经阅读了将GZip压缩与自定义绑定结合使用的信息。 Is this the best course of action? 这是最好的做法吗? the implementation documentation is very thin. 实施文档非常薄。

Failing that, is it likely that Net TCP binding could prove more efficient and if so how is this implemented when hosting a WCF service in a Winforms app rather than with IIS? 如果不这样做,是否有可能证明Net TCP绑定会更有效?如果是这样,当在Winforms应用程序中而不是与IIS中托管WCF服务时,如何实现此目的?

Unfortunately, the user requirements dictate that the whole view is returned to the client UI, I cannot page or async the results. 不幸的是,用户需求表明整个视图都返回到客户端UI,我无法分页或异步处理结果。

I have serious concerns over the statement 我对此声明感到严重关切

I have a WCF service using Entity Framework 6 hosted in a simple Windows Forms app 我有一个使用Entity Framework 6的WCF服务,该服务托管在一个简单的Windows Forms应用程序中

This paints a very confused picture to me. 这给我描绘了一幅非常困惑的图画。 It suggests that you have a "master" WPF app with the service in it, and then you distribute a bunch of WPF client apps which have the WCF client in them? 它建议您有一个带有服务的“主” WPF应用程序,然后再分发一堆其中装有WCF客户端的WPF客户端应用程序? The config sample you have provided defines a service client, not a service host. 您提供的配置示例定义了服务客户端,而不是服务主机。 There are many reasons why a WPF app is a very unsuitable host for a wcf service. WPF应用程序不适合用作wcf服务的宿主有很多原因。

The user edits articles from all over the world. 用户编辑来自世界各地的文章。 The articles are defined by country. 文章按国家/地区定义。 Therefore I can't serve up say TOP 200 as then the user will only receive 'Afghanistan' articles. 因此,我无法说出前200名,因为用户只会收到“阿富汗”文章。 They need to be able to scroll to their country of interest 他们需要能够滚动到感兴趣的国家

This is the key to addressing your problem. 这是解决您的问题的关键。 The data can be effectively sharded (or even exposed using views) into smaller sets of data, maybe by country and date as an example. 该数据可以是有效地分片 (或甚至使用视图曝光)成更小的数据集,可能因国家和日期,例如,

Failing that, is it likely that Net TCP binding could prove more efficient and if so how is this implemented when hosting a WCF service in a Winforms app rather than with IIS? 如果不这样做,是否有可能证明Net TCP绑定会更有效?如果是这样,当在Winforms应用程序中而不是与IIS中托管WCF服务时,如何实现此目的?

Yes! 是! netTcpBinding is much faster than http. netTcpBinding比http 快得多 That would certainly speed stuff up. 那肯定会加快速度。 You can use it over the internet but be aware that firewalls block TCP traffic on unopenned ports. 您可以通过Internet使用它,但请注意防火墙会阻止未打开端口上的TCP通信。

The wcf hosting container being WPF doesn't limit you to choice of transport bindings, but remains a very unorthodox choice. 作为WPF的wcf托管容器不会限制您选择传输绑定,但仍然是非常不合常规的选择。

When I run SQL Server Profiler on the db I can see that the query itself is very fast 当我在数据库上运行SQL Server Profiler时,我可以看到查询本身非常快

You have you used a SQL profiler, but you haven't provided any profiling information related to your WCF service, EF etc. which is much more important for troubleshooting this. 您使用过SQL事件探查器,但未提供任何与WCF服务,EF等有关的分析信息,这对于解决此问题更为重要。

Assuming your message size is 4KB, that would mean you are transferring dozens of MB over the wire at once, and in addition using buffering on both ends, which is not optimal for big payloads. 假设您的消息大小为4KB,这意味着您一次要通过网络传输数十MB的数据,此外还要在两端使用缓冲,这对于大负载而言并不是最佳选择。 Default XML Serialization/Deserialization of those records is a problem too, because its slow. 这些记录的默认XML序列化/反序列化也是一个问题,因为它很慢。 Pulling 11K using an ORM like EF is also not a good idea, because its slower than ADO.NET or MicroORMs. 使用像EF这样的ORM提取11K也不是一个好主意,因为它比ADO.NET或MicroORM慢。 So your whole architecture is wrong. 因此,您的整个体系结构是错误的。

I've tried to stream the response, didn't make any difference. 我尝试流式传输响应,没有任何区别。

Streaming is more efficient for big messages than Buffering, but it must be implemented correctly on the server, and especially on the client to have an effect. 对于大消息,流传输比“缓冲”更为有效,但是必须在服务器上(尤其是在客户端上)正确实现流才能生效。 If you use streams the wrong way, they could be slower than buffering. 如果以错误的方式使用流,则它们可能比缓冲慢。

However, optimizing the current implementation is not the right approach, your actual problem is the assumption you need 11K records upfront on the UI. 但是,优化当前实现不是正确的方法,您的实际问题是假设您需要在UI上预先存储11K条记录。 You should re-think your UI architecture and pull data on demand. 您应该重新考虑UI架构并按需提取数据。

Unfortunately, the user requirements dictate that the whole view is returned to the client UI, I cannot page or async the results. 不幸的是,用户需求表明整个视图都返回到客户端UI,我无法分页或异步处理结果。

One of the techniques you could use is infinite scrolling . 您可以使用的一种技术是无限滚动 There are many more. 还有更多。

In addition, you should use Async IO whenever you are dealing with remote services, unless you want to kill the scalability of your app. 此外,除非要终止应用程序的可伸缩性,否则在处理远程服务时都应使用Async IO。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM