none
Synchronization Per OperationContract RRS feed

  • Question

  • At the risk of sounding naïve, when does the WCF Dispatcher dispatch operations.  My question, in this instance, relates to callback.  Let's say I have a callback defined as follows:

    public interface ISampleCallback
    {
        [OperationContract(IsOneWay = true)]
        void Echo(string message);
    }

    And let's also say I have an implementation of the callback as follows:

    [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
    public class SampleCallback :
        ISampleCallback
    {
        private object myLock = new object();
    
        public void Echo(string message)
        {
     	lock(myLock)
            {
                Console.WriteLine(message);
            }
        }
    }

    Finally, for these purposes let's assume I'm using NetTcpBinding, which if my understanding is correct, should enforce that the messages from the server reach the client in the order they were sent (TCP/IP's native message ordering). 

    If the server invoked the callback operations, first sending the message "Hello", and then sending the message "World". 

    1. Is my TCP/IP message ordering assumption correct, that the messages arrive in order, "Hello", then "World"?
    2. Since the callback is defined with ConcurrencyMode.Multiple, at what point does the dispatcher dispatch the second message.  Is there ever a case whereby even though I am using a lock at first statement of my implemented Echo method, somehow, the second message makes it to the lock statement first, resulting in the output of "World" then "Hello"?

    The reason I ask this question is that I have a more complicated scenario whereby I have multiple callback operations, and what I really want is synchronization per OperationContract.  In the past my approach for this issue has been to set the ConcurrencyMode to Single, and immediately inside my Operation "re"-dispatch the message to an internally managed ProducerConsumerQueue.

    Tuesday, April 16, 2013 6:59 AM

Answers

  • TCP/IP will ensure that your messages are in order at the transport layer.  Using ConcurrencyMode.Multiple means that those messages will be dispatched immediately to the service as soon as they are received and that there is no guarantee that those messages will be executed in the same order they were received.  Once they are dispatched to the service their order of execution is at the mercy of the runtimes execution of the threads they were executed on.

    If you review the content on WCF concurrency from http://msdn.microsoft.com/en-us/library/orm-9780596521301-02-08.aspx you can see the statement for a service instance (also relevant for a callback instance) that "...when a service instance is configured with ConcurrencyMode.Multiple, WCF will not queue up the client messages and dispatch them to the service instance as soon as they arrive".  Reading later in the article there is specific mention of callbacks; "When you configure the callback class with ConcurrencyMode.Multiple, WCF will allow concurrent calls on the callback instance. This means you need to synchronize access in the callback operations, as shown in Example 8.21, "Manually synchronizing the callback with ConcurrencyMode.Multiple", because they could be invoked concurrently both by WCF worker threads and by client-side threads.".

    The simplest way to achieve synchronization across all operations is to use ConcurrencyMode.Single.  This will also give you ordering of your messages since they will be queued up by WCF in order (noting again that the TCP/IP transport guarantees they will be received in order) and dispatched one at a time.

    Tuesday, April 16, 2013 8:42 PM