I have a WebMethod which is used to return some HTML into a page after the initial load. The method is called through jQuery's ajax methods.
Everything works, however, there is a rather serious performance issue in loading the request state from these calls. With significant traffic CPU usage maxes out and actually kills the responsiveness of the entire site.
Using one profiler, System.Web.Handlers.ScriptModule.OnPostAcquireRequestState() is called out as the culprit with almost 100% of the call's duration.
Another profiler calls out System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData).
So I can reproduce the behavior locally with a load test, but with the culprit in the library I'm at a loss as to how to address it. Are there any 'gotchas' that can cause the context to be expensive to recover? Can I simply remove the context from the WebMethod?
It turned out the problem was having the WebMethod within the Page class. This forced the WebMethod to load with Session State, which has a reader/writer lock on the Session object. This forced the requests to execute synchronously, queuing up requests waiting for the lock to open.
I could not force the WebMethod within the page to not load the Session, or even load it as read only. Moving the WebMethod into its own WebService allowed this - and solved the problem.
This resolved the CPU 'lockup' on entering the WebMethod, and allowed the methods to execute concurrently greatly helping the page's load time.