WCF Service and Threading

I have created a simple WCF (.NET 3.5) service which defines 10 contracts which are basically calculations on the supplied data. At the moment I expect quite few clients to make a call to some of these contracts. How do I make the service more responsive ? I have a feeling that the service will wait until it process one request to go to the next one. How can I use multithreading in WCF to speed things up ?

Answers


While I agree with Justin's answer, I believe some more light can be shed here on how WCF works.

You make the specific statement:

I have a feeling that the service will wait until it process one request to go to the next one. How can I use multithreading in WCF to speed things up ?

The concurrency of a service (how many calls it can take simultaneously) depends on the ConcurrencyMode value for the ServiceBehavior attached to the service. By default, this value is ConcurrencyMode.Single, meaning, it will serialize calls one after another.

However, this might not be as much of an issue as you think. If your service's InstanceContextMode is equal to InstanceContextMode.PerCall then this is a non-issue; a new instance of your service will be created per call and not used for any other calls.

If you have a singleton or a session-based service object, however, then the calls to that instance of the service implementation will be serialized.

You can always change the ConcurrencyMode, but be aware that if you do, you will have to handle concurrency issues and access to your resources manually, as you have explicitly told WCF that you will do so.

It's important not to change these just because you think that it will lead to increased performance. While not so much for concurrency, the instancing aspect of your service is very much a part of the identity of the service (if it is session or not session-based) and changing them impacts the clients consuming the service, so don't do it lightly.

Of course, this speaks nothing to whether or not the code that is actually implementing the service is efficient. That is definitely something that needs looking into, when you indicate that is the case.


This is definitely pre-mature optimization. Implement your services first and see if there's an issue or not.

I think you'll find that you are worrying about nothing. The server won't block on a single request as that request processes. IIS/WCF should handle things for you nicely as-is.


I'm not familiar with WCF, but can the process be async? If you are expecting a huge amount of data and intensive calculations, one option could be to send an id, calculate the values in a separate thread and then provide a method to return the result using the initial id.

Something like:

 int id = Service.CalculateX(...);
 ...
 var y = Service.GetResultX(id);

By default the Instancing is PerSession. See WCF Service defaults

However if you use a session binding that doesn't support sessions (like BasicHttpBinding) or the the channel/client does not create a session then this behaves like PerCall

See [Binding type session support] (https://docs.microsoft.com/en-us/dotnet/framework/wcf/system-provided-bindings).

Each WCF client object will create a Session and for each session there will be a server instance with a single thread that services all calls from that particular WCF client object synchronously.

Multiple clients therefore would each have their own session and therefore server instance and thread by default and would not block each other. They will only affect each other on shared resources like DB, CPU etc.

See Using sessions

Like others suggested you should make sure the implementation is efficient BEFORE you start playing with the Instancing and Concurrency modes.

You could also consider client side calculations if there is no real reason to make a call to the server.


Need Your Help

How to resolve Error listenerStart when deploying web-app in Tomcat 5.5?

java spring deployment tomcat wicket

I've deployed an Apache Wicket web-application that uses Spring and Hibernate to my Tomcat 5.5 instance. When I navigate to the Tomcat Manager interface I see that the web-application I deployed is...

Calling finish() After Starting a New Activity

android android-activity message-queue

The first Activity that loads in my application is an initialization activity, and once complete it loads a new Activity. I want to ensure if the user presses 'Back' they go straight to the Launche...