I'm developing an Ajax-based application which makes heavy use of server calls to a WCF layer that communicates with a DB.
Whenever I effect from the client (an ASP.NET page) many calls within a short span of time to the underlying WCF services, the system hangs and goes into a idle state.
How can I handle such concurrency problems?
Thanks.
I suspect you have turned on [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
in your .svc and Web.config
Either you do not need Session and disabling AspNetCompatibilityRequirements will solve your problem.
Or may be you need it ReadOnly, so you can change SessionStateBehavior for specific svc in Global.asax.cs. The sequential blocking will stop.
protected void Application_BeginRequest(object sender, EventArgs e) {
if (Request.Path.Contains("AjaxTestWCFService.svc")) {
HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.ReadOnly);
}
}
Be warned however that SessionStateBehavior.ReadOnly will prevent writing to sessions without throwing exception. Written values will be returned as null.
If you really need Read/Write Session in you WCF service, you may try using the SQLServer aspsessionstate mode that may not expose the same blocking behaviour.
Without your configuration is hard to help, but
- are clients disposed/chanell closed correctly after calls?
- is your service per call, singleton or per session?
- have you tried Fiddler or other trace tool to catch your http traffic?
Well, assuming that the problem isn't DB concurrency, or web server hardware related, here's something to try...
WCF has some throttling defaults that caused a similar problem with one of my apps. The defaults were VERY low (something like 20 concurrent calls/sessions/instances)
Add the following to your config:
<!--add a behavior to modify the throttling -->
<behaviors>
<serviceBehaviors>
<behavior name="LessThrottlingBehavior">
<serviceThrottling
maxConcurrentCalls="100"
maxConcurrentSessions="100"
maxConcurrentInstances="100"
/>
</behavior>
</serviceBehaviors>
</behaviors>
<!-- modify the service to point to this behavior -->
<services>
<service name="MyWCFServer.WCFServer" behaviorConfiguration="LessThrottlingBehavior">
</service>
</services>
If the WCF layer is communicated over HTTP, you possibly hit the maximum number of outgoing connections the HTTP layer does.
http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit.aspx
The default value in the server environment is 10 which means that there could be at most 10 concurrent outgoing connections from your application server to the WCF layer. Just change this value to whatever larger depending on the estimated number of concurrent WCF calls.
Specifically, put this into the Application_Start
in your front web application (the one that calls WCF services, NOT the one with WCF services):
System.Net.ServicePointManager.DefaultConnectionLimit = 200;