wcf多个并行调用不能正常工作:调用之间的延迟和在少数线程中工作



我们正在尝试创建一个简单的WCF服务示例,该示例对WCF的同一方法进行多个并行调用。但我们面临一些问题:

  1. 我们正在计算从WCF服务方法获得结果的时间,我们发现在多个并行调用(同时调用WCF)之间,执行方法之间存在延迟(看起来它们是同步执行的,或者调用之间存在一些延迟)
  2. 此外,我们不能并行执行超过35-40个线程——之后我们得到了一个异常"无法连接到端点网络。tcp://localhost:9002/CalcService.错误代码TCP 10061">
  3. 此外,在我们的代码中,无论哪个值具有参数stb。MaxConcurrentCalls–每次我们最多可以进行10次调用。所以,请有人帮助我们解决我们的问题,并展示如何在并行模式下正确使用WCF服务和许多连接

以下是来自客户端和WCF服务的部分代码:

CalcService.cs:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple,
IncludeExceptionDetailInFaults = true, MaxItemsInObjectGraph = int.MaxValue)]
public class CalcService : ICalcService
{
#region ICalcService Members
public DateTime Foo(long id, DateTime dateTime)
{
Thread.Sleep(5000);
return DateTime.Now;
}
#endregion
}

FooWinService.cs:

public partial class FooWinService : ServiceBase
{
private ServiceHost m_svcHost;
public FooWinService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
ServicePointManager.DefaultConnectionLimit = 10000;
ContractDescription contractDescription = new ContractDescription("test");
contractDescription.ProtectionLevel = ProtectionLevel.None;
//contractDescription.ContractType = contractType;
//contractDescription.ConfigurationName = contractType.FullName;
contractDescription.SessionMode = SessionMode.Allowed;
if (m_svcHost != null) m_svcHost.Close();
// string strAdrHTTP = "http://localhost:9001/CalcService";
string strAdrTCP = "net.tcp://localhost:9002/CalcService";
Uri[] adrbase = {new Uri(strAdrTCP)};
m_svcHost = new ServiceHost(typeof (CalcService), adrbase);
var mBehave = new ServiceMetadataBehavior();
mBehave.MetadataExporter.ExportContract(contractDescription);
m_svcHost.Description.Behaviors.Add(mBehave);
//BasicHttpBinding httpb = new BasicHttpBinding();
//m_svcHost.AddServiceEndpoint(typeof(WCFCalcLib.ICalcService), httpb, strAdrHTTP);
//m_svcHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
var stb = m_svcHost.Description.Behaviors.Find<ServiceThrottlingBehavior>();
if (stb == null)
{
stb = new ServiceThrottlingBehavior();
m_svcHost.Description.Behaviors.Add(stb);
}
stb.MaxConcurrentSessions = 1000;//влияет
stb.MaxConcurrentCalls = 1000;//пофик
stb.MaxConcurrentInstances = 1000;//влияет

var sba = m_svcHost.Description.Behaviors.Find<ServiceBehaviorAttribute>();
if (sba == null)
{
sba = new ServiceBehaviorAttribute();
m_svcHost.Description.Behaviors.Add(sba);
}
sba.MaxItemsInObjectGraph = int.MaxValue;
sba.InstanceContextMode = InstanceContextMode.PerCall;
sba.ConcurrencyMode = ConcurrencyMode.Multiple;
var tcpb = new NetTcpBinding();
//tcpb.MaxConnections = 1000;
m_svcHost.AddServiceEndpoint(typeof (ICalcService), tcpb, strAdrTCP);
m_svcHost.AddServiceEndpoint(typeof (IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(),
"mex");
m_svcHost.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.None;
m_svcHost.Open();
}
protected override void OnStop()
{
if (m_svcHost != null)
{
m_svcHost.Close();
m_svcHost = null;
}
}
}

和客户:

private static void Main(string[] args)
{
try
{
Console.WriteLine("Using TCP Binding");
ServicePointManager.DefaultConnectionLimit = 10000;
for (int i = 1; i <= 35; i++)
{
int id = i;
var thread = new Thread(() =>
{
var objCalcClient1 = new CalcServiceClient("NetTcpBinding_ICalcService");
var binding = (NetTcpBinding)objCalcClient1.Endpoint.Binding;
binding.MaxConnections = 10000;
OperationDescriptionCollection operations = objCalcClient1.Endpoint.Contract.Operations;
foreach (OperationDescription operation in operations)
{
operation.Behaviors.Find<DataContractSerializerOperationBehavior>().MaxItemsInObjectGraph = 2147483647;
}
DateTime startTime = DateTime.Now;
objCalcClient1.Open();
DateTime gettedTime = objCalcClient1.Foo(id, startTime);
TimeSpan timeToPerform = gettedTime - startTime;
Console.WriteLine("Time to get result for id {0} is {1}", id, timeToPerform);
});
thread.Start();
}
}
catch (Exception eX)
{
Console.WriteLine("There was an error while calling Service [" + eX.Message + "]");
}
Console.WriteLine("I've done it!");
Console.ReadLine();
}

所以,请有人帮助我们解决我们的问题,并展示如何在并行模式下正确使用WCF服务和许多连接。

谢谢你,

问题的原因是:

我们没有为线程池中的线程设置值。

当我们使用方法ThreadPool.SetMinThreadsThreadPool.SetMaxThreads设置值时我们对WCF服务的请求正在并行处理。执行的请求数等于线程池中的线程数。

也许这对某些人会有所帮助。

在您的客户端代码中,我在任何地方都看不到对objCalcClient1.Close()的调用。

相关内容

  • 没有找到相关文章