title: Prevent deadlock issue with WCF duplex callback service
body: <p>I have a problem with a self-hosted wcf duplex callback service. I get an <code>InvalidOperationException</code> with message: </p>
  
  <blockquote>
    <p>This operation would deadlock because the reply cannot be received
    until the current message completes processing. If you want to allow
    out-of-order message processing, specify ConcurrencyMode of Reentrant
    or Multiple on CallbackBehaviorAttribute.</p>
  </blockquote>
  
  <p>Here is my service behavior:</p>
  
  <pre><code>[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode =  ConcurrencyMode.Reentrant, UseSynchronizationContext = true)]
  </code></pre>
  
  <p>Here is my service contract:</p>
  
  <pre><code> [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IClientCallback))]
  
  [ServiceContract]
  public interface IClientToService
  {
      [OperationContract(IsOneWay = false)]
      LVSSStatus GetLvssStatus();
  
      [OperationContract(IsOneWay = true)]
      void PickSpecimen(long trackingNumber, int destCode);
  
      [OperationContract(IsOneWay = true)]
      void CancelCurrentPickTransaction();
  }
  </code></pre>
  
  <p>Here is my callback interface:</p>
  
  <pre><code>public interface ILvssClientCallback
  {
      [OperationContract(IsOneWay = true)]
      void SendClientCallback(LvssCallbackMessage callbackMessage);
  
      [OperationContract(IsOneWay = false)]
      List&lt;SpecimenTemplateDescriptor&gt; GetTemplateDescriptorList(DrawerLayout drawerLayout);
  
      [OperationContract(IsOneWay = false)]
      SpecimenTemplate SelectSpecimenTemplate(string templateName, int version);
  
      [OperationContract]
      void SpecimenStoredInContainer(string containerID, bool isValidRackID, int rackRow, int rackCol, int deckRow, int deckCol,
       int drawerRow, int drawerCol, long trackingNumber, RobotErrors robotError);
  
      [OperationContract]
      void LvssRobotStatusChange(LVSSStatus status);
  }
  </code></pre>
  
  <p>I understand that the <code>InvalidOperationException</code> is caused when a callback operation is invoked on the client, the service is already locked for the processing of a current operation. So, a deadlock occurs.</p>
  
  <p>I have tried changing my ConcurrencyMode to multiple, and UseSynchronizationContext to false. </p>
  
  <p>I still see two problems with my service:</p>
  
  <p><strong>First:</strong>  The following service operation freezes my client wpf application when <code>GetLvssStatus()</code> is called rapidly (by clicking the UI button rapidly).  This method is not one way, and returns an enumerated type from the service back to the client synchronously.   </p>
  
  <pre><code>    [OperationContract(IsOneWay = false)]
      LVSSStatus GetLvssStatus();
  </code></pre>
  
  <p><strong>* What causes my wpf application to freeze in this case?
  *</strong> What can I do to prevent the application from freezing?
  If I use backgroundworker thread as an asynchronous call, the application does not freeze.  I really need this method to work synchronously. </p>
  
  <p><strong>Second:</strong> When I assign the callback method LvssRobotStatusChange to <code>IsOneWay = true</code>, I get an ObjectDisposedException: Cannot access a disposed object.  Object name: <code>'System.ServiceModel.Channels.ServiceChannel'</code>.</p>
  
  <pre><code>    [OperationContract(IsOneWay = true)]
      void LvssRobotStatusChange(LVSSStatus status);
  </code></pre>
  
  <p><strong>* What causes this ObjectDisposedException?
  *</strong> Is it okay to omit the IsOneWay assignment in this case?  Omitting IsOneWay in this case allows the callback to complete without any exceptions.</p>
  
  <p><strong>* Could these issues be a result of a lack of thread safe code?<br>
  *</strong> If so, what is the best practice to make a ConcurrencyMode.Multiple service behavior thread safe?</p>
  
  <p>Any help with these questions is much appreciated.</p>
  
  <p><em>*</em> FIRST EDIT
  A little more information regarding creation of my duplex channel.  My wpf view model creates a proxy object that is responsible for handling creation of my channel. Any attempts so far to set my channel on a new thread on the client side result in an ObjectDisposedException when the service attempts to use the callback object.</p>
  
  <p><em>*</em> SECOND EDIT
  I believe my service should work if I can get the operation contracts with void method to set IsOneWay = true.  With concurrency of reentrant, the main channel thread should let these methods pass through regardless of any locking.<br>
  Here is my callback interface:</p>
  
  <pre><code>public interface ILvssClientCallback
  {
      [OperationContract(IsOneWay = true)]
      void SendClientCallback(LvssCallbackMessage callbackMessage);
  
      [OperationContract]
      List&lt;SpecimenTemplateDescriptor&gt; GetTemplateDescriptorList(DrawerLayout drawerLayout);
  
      [OperationContract]
      SpecimenTemplate SelectSpecimenTemplate(string templateName, int version);
  
      [OperationContract(IsOneWay = true)]
      void SpecimenStoredInContainer(string containerID, bool isValidRackID, int rackRow, int rackCol, int deckRow, int deckCol,
       int drawerRow, int drawerCol, long trackingNumber, RobotErrors robotError);
  
      [OperationContract(IsOneWay = true)]
      void LvssRobotStatusChange(LVSSStatus status);
  }
  </code></pre>
  
  <p>When I set method LvssRobotStatuschange operation contract to IsOneWay = true, my cached callback channel throws a CommunicationObjectAbortedException. For some reason my callback property is being aborted.  </p>
  
  <p>***What can cause a callback channel to become aborted?</p>