Click here to Skip to main content
15,883,978 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
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:

C#
[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:

C#
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:

C#
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();
    }
}


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,
Posted

1 solution

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!
 
Share this answer
 
Comments
Dec_La 9-Nov-22 4:04am    
Hi,

I have the same problem on a Linux machine with the compatible Mono .NET Framework. I tryed this solution but it doesn't solve the problem.

It seems that the requests are not dispatched into/with a thread from the ThreadPool, they are still processed sequencialy.

Any idea? Is there another thing to configure for the ThreadPool with Mono?

Thank you

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900