Compartilhar via


Serialization of Client Calls

I'm making multiple calls to a service and all of the other calls sit waiting until the first call completes. How do I make the service process multiple calls at the same time?

If a service doesn't accept multiple, simultaneous calls from your client, then you have to figure out whether the problem is actually on the client or service.

On the client side, what typically goes wrong here is that the first call blocks all other progress. After the first call completes, you can see multiple calls going out to the service. This is caused by the first call being responsible for opening the connection to the service. You can choose to either open a connection to the service manually by calling Open on the client, or otherwise the first call will automatically open a connection if there isn't one already. Until the connection to the server is established, none of the other calls can proceed and that causes the blocking behavior. The solution is to always open the client connection yourself ahead of time by calling Open so that this process is hopefully complete by the time you want to start making calls.

If every call blocks, even after the first one, then this is probably due to the service configuration. There are two knobs that control whether multiple calls are allowed into the service called InstanceContextMode and ConcurrencyMode. You can set both of these knobs through a service behavior.

InstanceContextMode controls how often we'll create a new instance. There will only ever be one context if you pick Single and there can be multiple contexts if you pick PerSession or PerCall. PerSession is probably the sweet spot but requires your channel stack to serve up sessionful channels, as from buffered TCP or from reliable messaging. It can be expensive to make your channel stack sessionful if it does not already support sessions from the protocols that you've picked.

ConcurrencyMode controls how many threads we'll let into a service instance. There will only ever be one thread per instance if you pick Single or Reentrant, although Reentrant allows a thread to leave from a call and later come back in. There can be more than one thread per instance if you pick Multiple. You really don't have a choice about ConcurrencyMode because you either wrote the service to support multiple threads or you didn't. I don't see a compelling reason for your service to support multiple threads but restrict it to only have one.

You should now be able to spot how InstanceContextMode and ConcurrencyMode can work together to either allow or prevent clients from making multiple calls.

Next time: Replacing an Existing ASMX Service with WCF

Comments

  • Anonymous
    January 11, 2007
    Why are there two MSMQ bindings? This is an easy question to answer: there are two bindings for MSMQ