为什么我的初始WCF调用真的很慢?

时间:2015-04-12 13:01:45

标签: .net performance wcf silverlight

我看到了一些我无法解释的奇怪的WCF通话时间,并且它在我的应用程序中引起了一些实际问题。我的WCF服务调用似乎需要花费数百毫秒,如果不长于它们应该持续几秒钟。

我已经在网络应用项目中设置了一个简单的SL5项目,只是为了减少变量,我仍然看到了糟糕的时间。

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

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

我会想象它正在做一些事情,比如建立初始频道,这就是正在接受命中的东西,然后在那之后调用只是重用它们,但是无论如何都要减少初始命中?在真实应用中为我的每个通话添加大量额外时间会让我失去性能。

以下是带有通话结果的F12的屏幕截图。你可以看到第一批电话需要很长时间,然后一切都变得美好而快速:

WCF call screenshot

以下是测试应用中的调用代码:

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>

1 个答案:

答案 0 :(得分:0)

第一次服务呼叫的响应时间越长,很可能是由WCF服务启动引起的。