views:

108

answers:

1

I am trying to simulate X number of concurrent requests for a WCF Service and measure the response time for each request. I want to have all the requests hit the Service at more or less the same time.

As the first step I spawned X number of Threads, using the Thread class, and have invoked the Start method. To synchronize all the requests, on the Thread callback I open the connection and have a Monitor.Wait to hold the request from being fired, till all the Threads are created and started. Once all the Threads are started, I call Monitor.PulseAll to trigger the method invocation on the WCF Client Proxy.

When I execute the requests this way, I see a huge delay in the response. A request that should just a few milliseconds, is taking about a second.

I also noticed huge lag between the time the request is dispatched and the time it was received at the service method. I measured this by send sending client time stamp as a parameter value to the service method for each request.

I have the following settings. Assume "X" to the Concurrent number of requests I want to fire. Also note with the following settings I don't get any Denial of Service issues.

  1. The Call chain is as follows,Client->Service1->Service2->Service3
  2. All Services are PerCall with Concurrency set to Multiple.
  3. Throttling set to X Concurrent calls, X Concurrent Instances.
  4. MaxConnections, ListenBacklog on the Service to X.
  5. Min/Max Threads of ThreadPool set to X on both Client and Server (I have applied the patch provided by Microsoft).

Am not sure if the response time I'm measuring is accurate. Am I missing something very trivial?

Any inputs on this would be of great help.

Thanks.

-Krishnan

A: 

If all your outgoing calls are coming from a single process, it is likely that the runtime is either consolidating multiple requests onto a single open channel or capping the number of concurrent requests to a single target service. You may have better results if you move each simulated client into its own process, use a named EventWaitHandle to synchronize them, and call #Set() to unleash them all at once.

There is also a limit to the number of simultaneous pending (TCP SYN or SYN/ACK state) outgoing TCP connections allowed by desktop builds of Windows; if you encounter this limit you will get event 4226 logged and the additional simultaneous connections will be deferred.

Jeffrey Hantin
Thanks for your response. I would try your recommendations.I’m creating a new instance of a WCF proxy and opening it explicitly on each thread before I invoke the method on the proxy. Do you still feel that a single open channel could be reused? Is there a way I could verify that? And would it help if I create Multiple AppDomains instead of Processes?
Krishnan
AppDomains might do it if you're using TCP transport; they're nearly processes anyway. You'll probably still run up against event 4226 though.
Jeffrey Hantin
Creating AppDomains doesn't seem to solve the problem. I notice more latency in the Responses. I'm trying to simulate just 10 concurrent requests.
Krishnan