【问题标题】:Why are my initial WCF calls really slow?为什么我最初的 WCF 调用真的很慢?
【发布时间】:2015-04-12 13:01:45
【问题描述】:

我看到了一些我无法解释的奇怪 WCF 调用时间,这导致我的应用程序出现了一些实际问题。我的 WCF 服务调用似乎花费了数百毫秒,甚至比应有的时间长。

我已经建立了一个简单的 SL5 项目,托管在一个网络应用项目中,只是为了减少变量,但我仍然看到糟糕的时间安排。

我有一个非常简单的 WCF 服务调用,我正在使用 ClientBase 实例化服务实例,然后我在紧密循环中调用该服务 30 次(异步)。

根据 IE F12 工具,问题在于前几次调用需要很长时间。我看到网络时间在 500 毫秒到 2000 毫秒之间。之后,所有的服务调用时间都下降到 100 毫秒以下。对我来说,问题是,当我在应用程序中调用一次服务时,我会看到这些初始延迟,这意味着每次调用服务时往往需要很长时间。我只进行了紧密循环测试,看看情况是否会随着时间的推移而变得更好,他们确实这样做了。

我想它正在做一些事情,比如建立初始通道,这就是受到打击的原因,然后调用只是重用它们,但无论如何有没有减少初始打击?在真正的应用程序中为我的每个通话添加大量额外时间正在扼杀我的表现。

这是 F12 的屏幕截图和调用结果。您可以看到第一批调用需要很长时间,然后一切都变得又快又好:

这是测试应用中的调用代码:

Private Sub TestWcfClientBase()
    Dim client = ServicesCommon.GetService()
    client.Proxy.BeginGetCurrentUser((AddressOf OnGetUserCompletedCommon), Nothing)
End Sub

.
.
.

Public Shared Function GetService() As ServiceClient(Of IServiceAsync)
    Dim service As New ServiceClient(Of IServiceAsync)("IServiceAsyncEndpoint")
    Return service
End Function

.
.
.

Public Class ServiceClient(Of T As Class)
    Inherits ClientBase(Of T)
    Implements IDisposable

    Private _disposed As Boolean = False

    Public Sub New()
        MyBase.New(GetType(T).FullName)
    End Sub

    Public Sub New(endpointConfigurationName As String)
        MyBase.New(endpointConfigurationName)
    End Sub

    Public ReadOnly Property Proxy() As T
        Get
            Return Me.Channel
        End Get
    End Property


    Protected Sub Dispose() Implements IDisposable.Dispose
        If Me.State = CommunicationState.Faulted Then
            MyBase.Abort()
        Else
            Try
            Catch
            End Try
        End If
    End Sub

End Class

客户端配置如下:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding
                name="NoSecurity"
                closeTimeout="00:10:00"
                openTimeout="00:01:00"
                receiveTimeout="00:10:00"
                sendTimeout="00:10:00"
                maxBufferSize="2147483647"
                maxReceivedMessageSize="2147483647"
                textEncoding="utf-8">
                <security mode="None" />
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint
            name="IServiceAsyncEndpoint"
            address="http://localhost/TestService.svc"
            binding="basicHttpBinding"
            bindingConfiguration="NoSecurity"
            contract="Services.Interfaces.IServiceAsync" />
    </client>
</system.serviceModel>

这是精简后的服务代码:

<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)>
<ServiceBehavior(InstanceContextMode:=InstanceContextMode.PerCall)>
Public Class TestProxy
    Implements IService

    Public Function GetCurrentUser() As WebUser Implements IServiceAsync.GetCurrentUser
        Dim user As New WebUser
        With user
            .User_Name = "TestUser"
        End With
        Return user
    End Function

End Class

这是服务配置:

      <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
    <bindings>
      <basicHttpBinding>
        <binding name="NoSecurity" closeTimeout="00:10:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" textEncoding="utf-8">
          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
        </binding>
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="TestProxyServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="TestProxyServiceBehavior" name="TestProxy">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="NoSecurity" contract="Services.Interfaces.IService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
  </system.serviceModel>

【问题讨论】:

    标签: .net performance wcf silverlight


    【解决方案1】:

    第一次服务调用的响应时间较长很可能是 WCF 服务启动造成的。

    【讨论】:

    • 我也是这么想的,但是为什么每次刷新托管 Silverlight 应用程序的页面时都会发生这种情况?我本来预计只会命中一次,但每次刷新托管页面时,我都会得到完全相同的行为。有什么方法可以确认吗?
    猜你喜欢
    • 1970-01-01
    • 2017-06-07
    • 2017-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    相关资源
    最近更新 更多