3
votes

I read many posts about wcf concurrency and instance context modes, I read CodeProject articles too about it but still can't get it to work.

Here is my client code (if you ask why i'm using an instance context it is because i will eventually test callbacks, but i'm not there yet, just try to do a simple request/response many times simultaneously)

    public void Run()
    {
        InstanceContext context = new InstanceContext(this);
        MyServiceReference.MyService service = new MyServiceReference.MyService(context);

        for (int i = 0; i < 10; i++)
        {
            int j = i;
            Thread t = new Thread(() => myFun((j + 1), service));
            t.Start();
        }
        countdownEvent.Wait();

        Console.ReadLine();
        service.Close();
    }

    private void myFun(int threadNo, MyServiceReference.MyServiceClient service)
    {
        Console.WriteLine(service.GetData1(threadNo));
        countdownEvent.Signal();
    }

This is the service code:

[ServiceContract(CallbackContract = typeof(IMyServiceCallback))]
public interface IMyService
{
    [OperationContract]
    string GetData1(int value);
}

public interface IMyServiceCallback
{
    [OperationContract]
    string GetData2(int value);
}

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext=false)]
public class MyService : IMyService
{

    public string GetData1(int value)
    {
        reponse = DateTime.Now.ToString();

        Thread.Sleep(5000);

        return "Request: " + value + ", Thread id: " + Thread.CurrentThread.ManagedThreadId + ", response: " + reponse;
    }

This is the output:

Request: 1, Thread id: 9, response: 2015-08-14 11:39:42
Request: 2, Thread id: 10, response: 2015-08-14 11:39:47
Request: 3, Thread id: 8, response: 2015-08-14 11:39:52
Request: 4, Thread id: 9, response: 2015-08-14 11:39:57
Request: 5, Thread id: 10, response: 2015-08-14 11:40:02
Request: 6, Thread id: 9, response: 2015-08-14 11:40:07
Request: 7, Thread id: 10, response: 2015-08-14 11:40:12
Request: 8, Thread id: 9, response: 2015-08-14 11:40:17
Request: 9, Thread id: 10, response: 2015-08-14 11:40:22
Request: 10, Thread id: 9, response: 2015-08-14 11:40:27

I would expect setting ConcurrencyMode to multiple would make the requests to run simultaneously by using multiple threads, but even if I see 3 thread used, operation still is executed sequentially (5 sec between each response), what am I missing ?

Every examples I saw were using an operation with void return and IsOneWay=True, is that why it does not work for me ? However I use a different thread on the client for each request so all requests should be done simultaneouly, even if each thread is waiting for its own response.

I'm running in debug with WCF Service Host and a NetTcpBinding, could running in debug affect concurrency ?

1
I think it could be due to using the same service client. By default sessions are enabled so it could be just executing them in sequence as being part of the same session. Can you try to put SessionMode.NotAllowed on your service behaviour? - Juan
SessionMode is on ServiceContract attribute not behaviour, but anyway it seems I can't turn off session with netTcpBinding. Why the same client session could not do simultaneous requests anyway ? - Jonathan
I tried using many different client and it work as expected (requests are executed simultaneously), but what if I want to use the same client ? impossible ? - Jonathan
I created almost exactly the same test with the same results!! The addition of [ServiceBehavior(UseSynchronizationContext = false)] fixed it for me. - SharpC

1 Answers

2
votes

Try to mark your service as InstanceContextMode.PerCall:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext=false)]
public class MyService : IMyService