user1438082
user1438082

Reputation: 2748

multithreaded server

I am writing a test WCF server with a method to add 2 numbers and wait a configurable number of milliseconds.

I have written a wcf client. When I open two instances of this client - on clientA the wait value is 50 seconds and on the other clientB the wait is 0 seconds. I expect that when client A is running (long process) client B will get its response immediately.

It is however not working. I have been following this tutorial WCF Concurrency

Why is it not working for me?

WCF Service

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;


namespace WCFService
{
    //[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,ConcurrencyMode = ConcurrencyMode.Multiple,UseSynchronizationContext = true)]
    //[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,ConcurrencyMode = ConcurrencyMode.Single)] 
    //[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
    //[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession,ConcurrencyMode = ConcurrencyMode.Multiple)]
    //[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession,ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class WCFJobsLibrary : IWCFJobsLibrary
    {

        public ReturnClass AddNumbers(int FirstNumber, int SecondNumber, int Delay) //Add two numbers and wait a predefined interval
        {
            ReturnClass myReturnClass = new ReturnClass(-1, null, null, 0);
            try
            {             

                myReturnClass.ErrorCode = 1;
                myReturnClass.Result = FirstNumber + SecondNumber;
                System.Threading.Thread.Sleep(Delay); // Wait
                return myReturnClass;

            }
            catch (Exception ex)
            {              
                myReturnClass.ErrorCode = -1;
                myReturnClass.ErrorMessage = ex.ToString();
                return myReturnClass;
            }

        }

    }
}

WCF Client

try
            {

                radTextBoxResult.Text = ""; // Reset Result
                ServiceReference1.WCFJobsLibraryClient Client = new ServiceReference1.WCFJobsLibraryClient();
                Client.Endpoint.Address = new System.ServiceModel.EndpointAddress(radTextBoxbaseAddress.Text);
                WCFClient.ServiceReference1.ReturnClass AddNumbers_Result;
                AddNumbers_Result = Client.AddNumbers(int.Parse(radTextBoxFirstNumber.Text), int.Parse(radTextBoxSecondNumber.Text), int.Parse(radTextBoxDelay.Text));


                if (AddNumbers_Result.ErrorCode < 0)
                {
                    // If exception happens, it will be returned here
                    MessageBox.Show(AddNumbers_Result.ErrorCode.ToString() + " " + AddNumbers_Result.ErrorMessage + " " + AddNumbers_Result.ExMessage);
                }

                else
                {

                    radTextBoxResult.Text = AddNumbers_Result.Result.ToString();

                }

            }

            catch (Exception ex)
            {

                MessageBox.Show(ex.Message.ToString());

            }

App.Config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="">
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                  <serviceThrottling maxConcurrentCalls="16" maxConcurrentInstances="2147483647" maxConcurrentSessions="10" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service name="WCFService.WCFJobsLibrary">
                <endpoint address="" binding="wsHttpBinding" contract="WCFService.IWCFJobsLibrary">
                    <identity>
                        <dns value="localhost" />
                    </identity>
                </endpoint>
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8732/Design_Time_Addresses/WCFService/WCFJobsLibrary/" />
                    </baseAddresses>
                </host>
            </service>
        </services>
    </system.serviceModel>
</configuration>

Upvotes: 0

Views: 176

Answers (2)

Peter Kiss
Peter Kiss

Reputation: 9319

The problem might be the InstanceContextMode = InstanceContextMode.PerSession setting becouse your 2 calls sharing the same session. Try InstanceContextMode = InstanceContextMode.PerCall.

Both of the calls using one instance of your service but if the first stops it for 50 seconds then the second call processiing will wait until the thread is back in business and served the first call.

Upvotes: 1

user1438082
user1438082

Reputation: 2748

the problem was that i was starting the service in a winform application on the main thread. You need to start WCF on a seperate thread as illustrated below.

C# Code

private void radButtonStartWCFService_Click(object sender, EventArgs e)
{
    try
    {
        Thread Trd = new Thread(() => StartWCFServer());
        Trd.IsBackground = true;
        Trd.Start();

        radButtonStartWCFService.Enabled = false;
        radButtonStartWCFService.Text = "WCF Server Started";

    }

    catch(Exception ex)
    {
        MessageBox.Show(ex.Message.ToString());
    }
}


private void StartWCFServer()
{

    try
    {
        sHost = new ServiceHost(typeof(WCFService.WCFJobsLibrary));
        sHost.Open();

    }

    catch (Exception ex)
    {

        MessageBox.Show(ex.Message.ToString());

    }
}

Upvotes: 0

Related Questions