tags:

views:

205

answers:

3

I have made a WCF service which is defined like this:

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

binding is done using netTcpBinding.

We support 50+ clients that call the server from time to time. Each client opens a channel using channelfactory once it is loaded and uses that channel for all calls (creates the channel and proxy only once).

we have built a small load tester that imitates the client by calling the server by 50 different threads at once (using 50 different channels). when we run this tester, after the 10th client tries to connect, all other client fail connecting. We have set throttling to 100.

My questions are:

  1. is it correct for each client to create a channel and use it through the client life time? or, do i need to use a using statement for each call to the server (create and distroy a new channel for each call).
  2. does the service have a limit of channel connections to it? other then throttling?
A: 

Have you checked the CAL limit on your server?

It's generally good practice to clean up if you're not using something, so I'd stick everything in a using statement.

Doobi
what is CAL limit?Each client calls the server every 1 minute (assumption), do you recommend i create a channel each time it calls the server?
gash25
using statements and wcf clients.....not good http://msdn.microsoft.com/en-us/library/aa355056.aspx
redsquare
Doh! Thanks for that.
Doobi
A: 

what is CAL limit? Each client calls the server every 1 minute (assumption), do you recommend i create a channel each time it calls the server?

gash25
+2  A: 

The number of concurrent connections to the server is controlled by both the WCF service throttling behavior, and also your machine (it's OS, really). Windows XP machines had a hard limit on 10 concurrent connections - could that be the problem? If you're running on a server, that limit should not apply.

The service throttling behavior also has a default for MaxConcurrentSessions which is 10 - and your netTcpBinding connections will all have a transport-level session going, so that's definitely also a problem.

You can change the settings of the service throttling behavior in your app's config file:

 <serviceBehaviors>
    <behavior  name="TcpMoreThan10">
      <serviceThrottling 
        maxConcurrentCalls="100" 
        maxConcurrentSessions="50" 
        maxConcurrentInstances="50" />
    </behavior>
  </serviceBehaviors>

and you'd have to add this service behavior to your <service> tag, of course, to enable it:

<service name="....." behaviorConfiguration="TcpMoreThan10">
     ....
</service>

If you have only up to 50 clients calling sporadically, and they're all "internal" clients using netTcpBinding, I don't see any good reason why you'd want to make this thing a multi-threaded singleton, really.

As a side-note: multithreaded singletons are notoriuosly hard to write, hard to get everything correct, you need to worry about concurrent access to your internal variables etc. - rather messy programming.

Why not use the default per-call instance mode? With this:

  • each request coming in tets his own, separate, isolated, freshly created instance of the service class
  • each service class instance only ever handles exactly one caller, so there's no need for messy and complicated multi-threaded programming models
marc_s
It is impossible for our service to use per-call because of performance, complextiy and other reasons.Do you recommend destroying the channel after each client call? or using the same channel?
gash25
@Gash25: actually, complexity with per-call would be much less than having a multi-threaded singleton...... performance shouldn't be a big issue, either, if your service constructor isn't overly complicated...
marc_s