wcf多个并行调用无法正常工作:调用之间的延迟和少量线程的工作 [英] wcf multiple parallel calls is not working correctly: delay between calls and working in few number of threads

查看:81
本文介绍了wcf多个并行调用无法正常工作:调用之间的延迟和少量线程的工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,

我们正在尝试创建WCF服务的简单示例,其中多个并行调用WCF的相同方法。但是我们遇到了一些问题:

1.我们正在计算从WCF服务方法获得结果的时间,我们发现在多个并行调用(同时调用WCF)之间我们有延迟在执行方法之间(看起来它们正在同步执行或者在调用之间有一些延迟)

2.此外,我们不能并行执行超过35-40个线程 - 之后我们得到了一个例外

无法连接到端点net.tcp:// localhost:9002 / CalcService。错误代码TCP 10061

3.此外,在我们的代码中,无论哪个值都有参数stb.MaxConcurrentCalls - 每次我们不能拨打不超过10个电话。



下面是客户端和WCF服务的部分代码:



CalcService.cs:



Hello,
We are trying to create simple example of WCF service with multiple parallel calls to the same method of WCF. But we faced with some problems:
1. We are calculating time for getting result from WCF service method, and we found that between multiple parallel calls (which are calling WCF at the same time) we have delay between executing methods (it looks like they are executing synchronously or with some delay between calls)
2. Also, we can’t execute more than 35-40 threads in parallel – after that we got an exception
"Can’t connect to endpoint net.tcp://localhost:9002/CalcService. Error code TCP 10061"
3. Also, in our code there is no matter which value has parameter stb.MaxConcurrentCalls – every time we can make no more than 10 calls.

Below there are some parts of code from client and WCF service:

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:






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;
        }
    }
}







和客户:






and Client:

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服务并正确连接多个连接。



谢谢,



So, please, could anybody help us to fix our problems and to show how to work with WCF service in parallel mode with many connections correctly.

Thank you,

推荐答案

您好!



问题的原因在于:

我们没有在ThreadPool中设置线程的值。

当我们使用方法ThreadPool.SetMinThreads和ThreadPool.SetMaxThreads

设置值时,我们对WCF服务的请求是并行处理的。执行的请求数等于ThreadPool中的线程数。



可能会对某人有所帮助。



谢谢!
Hello!

The reason of problem was in that:
we didn't set the value for threads in ThreadPool.
When we set values using methods ThreadPool.SetMinThreads and ThreadPool.SetMaxThreads
our requests to WCF service are processing parallel. Number of requests which are executed equals number of threads in ThreadPool.

May be it will be helpful for somebody.

Thank you!


这篇关于wcf多个并行调用无法正常工作:调用之间的延迟和少量线程的工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆