第一次调用 .NET Web 服务较慢

8
我正在从我的.NET WinForms应用程序调用一个.NET Web服务,两者都在.NET Framework 4.0中。在程序执行期间,第一次调用WebService的方法需要大约10-12秒的时间。后续调用只需要1-2秒钟。即使重新创建Web引用实例,后续调用仍然需要1-2秒钟。当WinForms应用程序重新启动时,再次出现第一次调用延迟,但后续调用则响应迅速。
在调用发生之前,Web引用实例被创建,并且不是延迟的一部分。
WinForms应用程序的XmlSerializers正在生成(并且我知道正在使用),但我不确定如何验证此操作。
延迟不是由于WebService端的首次运行编译而发生的。这是一个生产WebService,在整个工作日都在使用,并且其应用程序池保持在内存中。据我所见,延迟要么发生在客户端端,要么在第一次调用时客户端和服务器之间发生,但不会在后续调用中发生。
下一步该检查什么呢?有什么想法吗?

1
请注意,第一次调用会比较慢,但不应该太慢。 - tier1
1
我怀疑答案可能在这个问题/答案组合中:https://dev59.com/eWw05IYBdhLWcg3w11a0。特别是,我正在关注代理问题。 - spender
1
在出现故障的计算机的Internet选项中,您是否有“自动检测设置”来代理? - spender
@tkcsam:是的,我期望会有一点延迟,但绝不是我现在看到的这样。 - Brian M.
你可以使用详细的IIS请求日志来确定延迟是来自客户端还是Web端 - 你有任何相关信息吗? - Dan Puzey
显示剩余2条评论
5个回答

9
如spender所指出的,问题与代理检测有关。在Internet Explorer中关闭此功能可以解决问题,但在我的情况下不可行。
相反,有一个绕过默认代理和自动检测的解决方法。
将以下条目添加到app.config中允许某些URL绕过代理:
<configuration>
    <system.net>
        <defaultProxy>
            <bypasslist>
                <add address="server/domain name" />
            </bypasslist>
        </defaultProxy>
    </system.net>
</configuration>

更多信息可以在这里找到:<defaultProxy Element> on MSDN(英文)


你有一个运行在桌面上的WinForms客户端应用程序,改变Internet Explorer选项可以帮助解决问题吗?只是好奇,请告诉我! - Mare Infinitus
1
@MareInfinitus:这不是Internet Explorer的选项,而是wininet API的选项,Internet Explorer也使用它并提供了一个GUI进行配置。 - Ben Voigt

2
尝试将代理设置为空的WebProxy,即:

尝试将代理设置为空的WebProxy,即:

request.Proxy = new WebProxy(); 

您可以通过在应用程序的.Config文件中使用system.net部分中的defaultProxy键来覆盖代理设置。以下是禁用自动代理检测的方法:

<configuration >
  <system.net>
    <defaultProxy>
      <proxy bypassonlocal="true" usesystemdefault="false" />
    </defaultProxy>
</system.net>
</configuration>

http://weblog.west-wind.com/posts/2005/Dec/14/Slow-Http-client-calls-from-ASPNET-20-Make-sure-you-check-your-Proxy-Settings


1

抱歉打扰,但这个问题对我来说已经出现了很多次,每次都会忘记所有方面的内容。所以这里是列表(其他人也提到了一些)。

  • 将System.ServiceModel.BasicHttpBinding的BypassProxyOnLocal和UseDefaultWebProxy都设置为false。(您可以决定是在配置文件中还是通过代码实现。)
  • 将项目的“生成序列化程序集”属性从“自动”改为“启用”。
  • 确保您正在使用现代.NET框架。例如,4.6.1比4.5.2快大约60毫秒的第一次请求。
  • 在发布可执行文件上进行性能测试,而不是在VisualStudio中进行(因为VS在初始调用时会增加很大的额外开销,这并没有反映在实际发布的.exe构建中)。
  • 如果您正在使用持续运行的服务/站点,请考虑在启动时向服务器发送一个虚拟请求,只是为了让.NET预先序列化连接。同样,如果您正在编写一个运行并退出的应用程序,请考虑在程序启动时编写后台虚拟请求。
  • 确保您连接的服务不经常回收。每当IIS服务的应用程序池回收时,回收后的第一个请求可能需要花费一些时间。
  • 确保您连接的服务不休眠。默认情况下,服务在20分钟的不活动后会休眠——下一个请求的延迟类似于回收后的请求。

0

我曾经遇到过这个问题很多次 - 我讨厌它!!!哈哈。虽然我从未最终解决过它,但你可以尝试几件事情。首先,在启动时调用 Web 服务并先处理掉“痛点”!其次,尝试更改 Web 服务的 IIS 应用程序池 - 让它永远不会自动回收或至少在清晨的非常早的时间或每 10000 次请求时进行回收。

我知道这可能不是一个很好的答案,但希望能对你有所帮助!


编辑:

问题的一部分在于 Web 服务并非始终处于运行状态 - 它会休眠、回收等,直到需要时才会启动。值得阅读有关保持 Web 服务活动、5 9s 的正常运行时间等方面的知识!


不会有帮助。OP已经在问题中勾选了这些问题。 - spender
正确。这里与Apppool无关。但感谢您的建议。 - Brian M.
这个 Web 服务在我的测试期间确实是“始终”在线的。它每秒钟被客户端调用2-3次,大约从早上7点到晚上7点左右。我理解你所说的应用程序池回收等情况,但这里并不是这种情况。 - Brian M.
好的,只是做一些基础工作!我解决这个问题的唯一方法是在客户端启动时进行初始虚拟调用服务。很抱歉目前不能提供更多帮助! - Bertie
那么我的理解是,目前调用该服务的客户端是web客户端,而你遇到的问题来自使用Web Service Reference向导的一个.Net应用程序,对吗? - Bertie
客户端既有 .net winforms,也有 .net webforms,但在我的示例中,它是一个 winforms 应用程序。所有客户端都已通过 Visual Studio 的“添加 Web 引用”功能添加了 Web 引用。(问题已经解决,请参见下文) - Brian M.

0

我在我的 basicHttpBinding 上添加了这些设置,禁用了自动代理检测,并在第一次执行时获得了很大的加速。当然,如果您处于内部网络环境中,或者您知道根本不需要任何代理,那么这个方法会非常有效。

bypassProxyOnLocal="false"

useDefaultWebProxy="false"

希望这可以帮到您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接