我是 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/