WCF Channels AutoOpen vs Open Semantics

Wanted to write up a post on whats the difference between "auto" opening a WCF Channel and explicitly calling "Open" on it. Michael Maruchek posted a detailed and well explained post at https://blogs.msdn.com/mjm/archive/2006/11/13/auto-open-part-1.aspx. Waiting for part 2.

Since Micheal did such a wonderful job of explaining the design I just wanted to illustrate the behavior with a sample app.

I have a simple contract that has a Sync and Async version and the client will invoke a operation on the async contract 10 times. Lets see the difference in actual behavior when the channel is auto opened and explicitly opened.

First the contract definitions.

[

ServiceContract(Name="ISyncService")]

public interface IAsyncService

{

[

OperationContract(AsyncPattern=true, Action="SayHello")]

    IAsyncResult BeginSayHello(int id, AsyncCallback callback, Object obj);

    void EndSayHello(IAsyncResult ar);

}

[ServiceContract]

public interface ISyncService

{

[

OperationContract(Action="SayHello")]

    void SayHello(int id);

}

Here is the contract implementation. Notice the multiple concurrency that should allow concurrent processing of multiple messages.

[

ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple, InstanceContextMode=InstanceContextMode.Single)]

public class SyncService : ISyncService

{

#region

ISyncService Members

public void SayHello(int id)

{

Console.WriteLine("SayHello invoked with Id: {0}", id);

Thread

.Sleep(500);

}

#endregion

}

Finally the client code to invoke the service. We will introduce a small sleep to simulate some long processing.

IAsyncService channel = ChannelFactory<IAsyncService>.CreateChannel(binding, new EndpointAddress(ServiceAddress));

for (int i = 0; i < 10; i++)

{

channel.BeginSayHello(i, SayHelloCallback, channel);

}

This implies the "auto" open behavior. Lets see the output.

Issued all asynchronus requests. Waiting for them to complete.
SayHello invoked with Id: 0
SayHello invoked with Id: 1
SayHello invoked with Id: 2
SayHello invoked with Id: 3
SayHello invoked with Id: 4
SayHello invoked with Id: 5
SayHello invoked with Id: 6
SayHello invoked with Id: 7
SayHello invoked with Id: 8
SayHello invoked with Id: 9
All async requests completed

As you can see no matter how many times the client is run the server processes all the async invocations sequentially and in the order it was issued. This defeats the purpose of issuing async calls and having multiple concurrency mode on the server.

Lets see the output when the channel is explicitly opened. I just added the following line before issuing the requests.

((

IChannel)channel).Open();

Output is:

Issued all asynchronus requests. Waiting for them to complete.
SayHello invoked with Id: 0
SayHello invoked with Id: 2
SayHello invoked with Id: 4
SayHello invoked with Id: 5
SayHello invoked with Id: 1
SayHello invoked with Id: 3
SayHello invoked with Id: 7
SayHello invoked with Id: 6
SayHello invoked with Id: 8
SayHello invoked with Id: 9
All async requests completed

As you can see the output is truly async and truly concurrent.

Maheshwar Jayaraman