c# - WCF 性能问题

标签 c# wcf

我是 WCF 的新手,有一个性能问题。我有以下在客户端执行的代码:

    try
    {
      for (int i = 0; i < 20; i++)
      {
         stopwatch.Reset();
         stopwatch.Start();

         var psn = client.GetPsnByPsnId(21);
         var psnList = client.GetPsnBySmartBizClientId(2);
         var container = client.GetContainerByContainerId(3);
         var containerList = client.GetContainerBySmartBizClientId(2);

         stopwatch.Stop();
         Console.WriteLine(string.Format("Pass # {0} completed in {1} milliseconds", i + 1,stopwatch.ElapsedMilliseconds));
     }
   }
   catch (FaultException exception)
   {
      MessageBox.Show(string.Format("Error occurred. The error message is {0}", exception.Message));
   }
   finally
   {
      client.Close();
      client = null;
   }

此代码命中 WCF 服务,该服务作为 Windows 服务在 .NET 4.0 下使用 HTTP 绑定(bind)托管。我的问题是这个。第一次通过循环,在第一次 WCF 调用 (client.GetPsnByPsnID()) 时,有一个非常明显的延迟,实际上超过 10 秒。但是,在第一次调用之后,每个后续调用,每次通过循环,都需要 < 1 秒,正如我所期望的那样。我确定这是一个 WCF 问题,因为如果我在 WCF 之外调用第一个方法,我将获得 < 1 秒的性能。

任何人都知道可能导致初始延迟的原因是什么?

编辑:这是 Windows 服务的 OnStart 代码:

protected override void OnStart(string[] args)
{
   serviceHost = new ServiceHost(typeof(ServiceMethods),new Uri("http://111.111.111.111:1111/Psn"));

   // Add an endpoint and the methods the endpoint will support.
   serviceHost.AddServiceEndpoint(typeof(IServiceMethods), WcfConfiguration.GenerateBinding(Enumerations.WcfBindingType.HTTP), "");

   WcfConfiguration.CreateMexData(serviceHost);
   serviceHost.Open();
}

这是 GenerateBinding 方法:

public static System.ServiceModel.Channels.Binding GenerateBinding(Enumerations.WcfBindingType bindingType)
{
   System.ServiceModel.Channels.Binding binding = null;

   BasicHttpBinding httpBinding = new BasicHttpBinding();
   httpBinding.Security.Mode = ((bindingType == Enumerations.WcfBindingType.HTTP) ? BasicHttpSecurityMode.None : BasicHttpSecurityMode.Transport);
   httpBinding.OpenTimeout = new TimeSpan(0, 0, 30);
   httpBinding.SendTimeout = new TimeSpan(0, 0, 30);
   httpBinding.ReceiveTimeout = new TimeSpan(0, 0, 30);
   httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
   httpBinding.ReaderQuotas.MaxStringContentLength = httpBinding.ReaderQuotas.MaxStringContentLength;
   httpBinding.MaxReceivedMessageSize = httpBinding.MaxReceivedMessageSize;
   httpBinding.ReaderQuotas.MaxArrayLength = 1048576;
   httpBinding.MaxBufferSize = httpBinding.MaxBufferSize;

   binding = httpBinding;
   break;
   }
   return binding;
}

public static void CreateMexData(ServiceHost host)
{
  ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();

  behavior.HttpGetEnabled = true;
  host.Description.Behaviors.Add(behavior);
  host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
}

最佳答案

如果该服务在您的测试运行之间没有获得任何命中,它实际上可能正在关闭 WCF 服务应用程序,并且当一个新请求进入时它会完全重新启动该应用程序,这也会花费更多时间。这可以在 IIS 设置中更改(假设您在 IIS 中托管),以便工作进程需要更长的时间才能关闭,或者根本不关闭。

此外,WCF 会在您的第一次调用时建立 TCP/Http 连接,后续调用可能会使用池连接。不必重新建立 TCP/Http 连接可为您节省大量时间。

最后,对于您当前的实现,最好的情况是您每次迭代仍进行 4 次服务器往返。 batching your wcf calls together 可能会更好地为您服务减少往返。

关于c# - WCF 性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5996960/

相关文章:

c# - 取消 Windows 10 BackgroundDownloader

c# - 删除表行而不是隐藏在 rdlc 报告中

asp.net - 如何将 SOAP::Lite 与 WCF 结合使用?

wcf - 负载均衡器后面的 WCF 服务的 WSDL 生成

javascript - Ajax不调用WCF服务

c# - Sync Framework - 在不更改架构的情况下同步数据

c# - 检查数据库中的重复数据 (C#)

javascript - 将 C# Dto 类属性的首字母更改为的常见解决方案是什么

c# - 我的 ASMX 代理方法中的这些额外参数是什么?

WCF REST 服务在 WCFTestClient 中不可见