Blog from Saravanan Arumugam

Let us talk about Technologies

Monthly Archives: March 2011

This operation would deadlock because the reply cannot be received until the current Message completes processing.


I got the following exception when I attempted to create a Duplex channeled service.

Exception

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 ServiceBehaviorAttribute.

I got this exception because I didn’t change the concurrency mode of the service. By default the concurrency mode is single. But the duplex operation would require the service instance to be called concurrently.

Solution

As suggested in the exception message itself, when I set the Concurrency mode to Multiple it got resolved.

Reentrant is also applicable for duplex services however the choice of Multiple or Reentrant concurrency is up to the design.

    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]

    public class GreetingService : IGreetingService

Advertisements

Know the Service and Operation Behaviors


We usually get convinced with the default behavior of a WCF service and its operations. In scenarios where the simple is not sufficient, we tend to set the operation and service behaviors through code based on our need.

Setting a behavior is achieved through ServiceBehaviorAttribute and OperationBehaviorAttribute. The config file is another place for defining Service, Binding and Endpoint behaviors. But in this paper, I limit the discussion to the behaviors that can be set though these two attributes.

These attributes are applicable only on the Service definition not on the service declaration; in other words, use these attributes on the Service’s class definition, not on the Interface.

The typical Service having implemented the behavior attributes would look like this.

    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, 
        TransactionIsolationLevel = IsolationLevel.Serializable, 
        InstanceContextMode = InstanceContextMode.Single, 
        ReleaseServiceInstanceOnTransactionComplete = true)]
    public class BankingService : IBankingService
    {
        [OperationBehavior(ReleaseInstanceMode = ReleaseInstanceMode.None, 
            TransactionScopeRequired = true)]
        public double WithdrawMoney(int accountNumber, double amount) { }
    }

To make a decision on weather the current behavior of Service and operation is sufficient for your service needs or you want to change them, it is important to know the place to check the current behavior during the runtime.

The object useful to examine the behaviors is OperationContext. You can get the current context using OperationContext.Current.

 

Service Behaviors

The following list (screenshot) shows the configurable behaviors of the current service and their default values.

image

The service behavior is extracted with the following statement in Debug mode (with Quickwatch).

OperationContext.Current.Host.Description.Behaviors[typeof(ServiceBehaviorAttribute)]

Note: Besides the Host.Description, the service behavior can be found in various places of OperationContext.Current.EndpointDispatcher.DispatchRuntime. The list of service behaviors found in DispatchRuntime is listed at the end of this paper.

 

OperationBehaviors

The following list (screenshot) shows the configurable behaviors of a specified operation and their default values.

image

The operation behavior for a specific operation contract can be extracted using the following statement.

OperationContext.Current.EndpointDispatcher.DispatchRuntime.Operations["Greeting"]

Note: In the screenshot the IsOneway behavior is displayed as true since I have specified it explicitly. In reality, it’ll be false by default.

List of Service Behaviors found in DispatchRuntime

OperationContext.Current.EndpointDispatcher.DispatchRuntime.ConcurrencyMode

OperationContext.Current.EndpointDispatcher.EndpointAddress

OperationContext.Current.EndpointDispatcher.AddressFilter

OperationContext.Current.EndpointDispatcher.DispatchRuntime.

ReleaseServiceInstanceOnTransactionComplete

OperationContext.Current.EndpointDispatcher.DispatchRuntime.

TransactionAutoCompleteOnSessionClose

OperationContext.Current.EndpointDispatcher.DispatchRuntime.ValidateMustUnderstand

OperationContext.Current.EndpointDispatcher.DispatchRuntime.CallbackClientRuntime

OperationContext.Current.EndpointDispatcher.ContractName

OperationContext.Current.EndpointDispatcher.ContractNamespace

OperationContext.Current.EndpointDispatcher.DispatchRuntime.MessageInspectors

OperationContext.Current.EndpointDispatcher.DispatchRuntime.AutomaticInputSessionShutdown

OperationContext.Current.EndpointDispatcher.DispatchRuntime.SingletonInstanceContext

OperationContext.Current.EndpointDispatcher.DispatchRuntime.SynchronizationContext

OperationContext.Current.EndpointDispatcher.ChannelDispatcher.TransactionIsolationLevel

OperationContext.Current.EndpointDispatcher.ChannelDispatcher.TransactionTimeout

HTTP could not register URL … because TCP port 80 is being used by another application


When I used a Duplex channeled binding (wsDualHttpBinding), during the run time I received the following exception.

Exception:

HTTP could not register URL http://+:80/Temporary_Listen_Addresses/634f73f6-c612-4441-acf8-79ddd5c62f98/ because TCP port 80 is being used by another application.

This is because the port 80 is being used by the IIS (the default web site uses Port 80) and the callback from the service attempts to register the same port for communication.

Solution:

The solution to this is to instruct the WCF to use a different port. I had to add the following binding configuration.

    <bindings>

      <wsDualHttpBinding>

        <binding name="wsDualHttpBinding_IGreetingService" 

         clientBaseAddress="http://localhost:8088/clientCallbackUrl">

        </binding>

      </wsDualHttpBinding>

    </bindings>

I also had to specify the bindingConfiguration in endpoint to point to this.

<endpoint address="ws" binding="wsDualHttpBinding" 
contract="DuplexChannel.IGreetingService" 
bindingConfiguration="wsDualHttpBinding_IGreetingService"/>

 

But unfortunately specifying the clientBaseAddress in service configuration doesn’t take part in the WSDL. As a result clientBaseAddress won’t show up in the client side config. There is no negotiation happening during the runtime either.

So instead of providing the clientBaseAddress in the service side, create the proxy and config as usual and then provide the clientBaseAddress by modifying the client side configuration.

As a result, the client side configuration should typically be looking like this.

<configuration>
    <system.serviceModel>
        <bindings>
            <wsDualHttpBinding>
              <binding name="WSDualHttpBinding_IGreetingService"
                 clientBaseAddress="http://localhost:8088/clientCallbackUrl">
                <security mode="Message">
                  <message clientCredentialType="Windows" 
                          negotiateServiceCredential="true"
                      algorithmSuite="Default" />
                </security>
              </binding>
            </wsDualHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:54927/GreetingService.svc/ws"
                 binding="wsDualHttpBinding" 
                 contract="GreetingService.IGreetingService"
                 bindingConfiguration="WSDualHttpBinding_IGreetingService"
                 name="WSDualHttpBinding_IGreetingService">
                <identity>
                    <userPrincipalName value="xxx\xxxx" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

Note: By default the Visual Studio would not be able to register even http://localhost:8088/clientCallbackUrl if it is used for the first time due to security constraints.

Refer to HTTP could not register URL for further detail.

An alternate solution to using netsh command is to run the Visual Studio itself in Administrator mode.

Unrecognized element ‘wsDualHttpBinding’ in service reference configuration. Note that only a subset of the Windows Communication Foundation configuration functionality is available in Silverlight.


This is an extension to my previous post ServiceReference.ClientConfig is not populated with Service Reference

When I created a proxy and config file by using SvcUtil.exe, I had to copy the app.config content into ServiceReference.ClientConfig.

Note: Instead of creating app.config and copying it into ServiceReference.ClientConfig, I could have used /config:ServiceReference.ClientConfig switch directly in the SvcUtil.

The build was successful but while accessing the service, I got the following runtime exception.

Exception:

Unrecognized element ‘wsDualHttpBinding’ in service reference configuration. Note that only a subset of the Windows Communication Foundation configuration functionality is available in Silverlight.

 

Solution:

The solution was simple. Change the binding to basicHttpBinding, pollingDuplexHttpBinding or customBinding.

ServiceReference.ClientConfig is not populated with Service Reference


Exception:

I came across a strange behavior of Visual Studio. When I made a Service reference in my Silverlight application, the visual studio created the classes and schemas; but not the config file (ServiceReference.ClientConfig)

 

Solution:

The reasons for having ServiceReference.ClientConfig not populated could be many. But in my case, I was using wsDualHttpBinding in the service (a duplex channeled service).

wsDualHttpBinding and may other bindings are not supported by Silverlight. To be precise Silverlight supports only BasicHttpBinding, pollingDuplexHttpBinding (supported with Silverlight 4) and customBinding.

When I made some changes in the service and changed the binding as basicHttpBinding, the Service Reference update populated the ServiceReference.ClientConfig file.

It could have been better if the service reference threw exception saying that the Silverlight supports only a subset of WCF bindings, instead of completing the reference successfully leaving the Config file incomplete. Hopefully the future releases of Visual studio would do that.

 

The following forum helped me narrow the issue.

Failed to generate the service reference WCF service