Wednesday, March 28, 2012

PageMethod calls are not asynchronous

I created a test app to try out the PageMethod functionality. I can make four calls to a PageMethod and I can verify that they are called asynchronously via the tracing statements. So I moved the test page into an existing website that I converted to AJAX and it appears that the methods are call synchronously. Is there a setting somewhere that I might be missing? It is the exact same page in both sites. Any suggestions are greatly appreciated. I've included the log results and methods for reference.

Test App Trace (This is the expected result. Notice that all of the "In Server Method" entries occur before any of the "Out Server Method" entries):

Post PageMethodsfor 1Post PageMethodsfor 2Post PageMethodsfor 3Post PageMethodsfor 4In Server Method: 1 - 633088835535430360In Server Method: 2 - 633088835538237248In Server Method: 3 - 633088835543249548In Server Method: 4 - 633088835548261848Out Server Method: 4 - 633088835573122856Out Server Method: 3 - 633088835578335648Out Server Method: 2 - 633088835590766152Out Server Method: 1 - 633088835600089030

Converted App Trace(This is not the expected result. Notice that the "In Server Method" entries alternate with the "Out Server Method" entries):

Post PageMethodsfor 1
Post PageMethodsfor 2
Post PageMethodsfor 3
Post PageMethodsfor 4
In Server Method: 1 - 633088837286126504
Out Server Method: 1 - 633088837375044706
In Server Method: 2 - 633088837378352824
Out Server Method: 2 - 633088837407023180
In Server Method: 3 - 633088837408627116
Out Server Method: 3 - 633088837421057620
In Server Method: 4 - 633088837423664016
Out Server Method: 4 - 633088837477596364

Server Method:

 [WebMethod]public static int GetHitCount(int grid) { Debug.WriteLine("In Server Method: " + grid.ToString() +" - " + DateTime.Now.Ticks.ToString());int sleep = rand.Next(1000, 10000); System.Threading.Thread.Sleep(sleep); // Sleep to slow down the process Debug.WriteLine("Out Server Method: " + grid.ToString() +" - " + DateTime.Now.Ticks.ToString());return rand.Next(1, 100); }

Client Methods:

function GetAllData() { PageMethodCall(1); PageMethodCall(2); PageMethodCall(3); PageMethodCall(4); } function PageMethodCall(context) { var waitImg = document.getElementById("imgWait" + context); waitImg.style.visibility =''; PageMethods.GetHitCount(context,OnSucceeded, OnError, context); Sys.Debug.trace('Post PageMethods for ' + context); }

Ok, I still don't have a good solution but I've found the problem. Though a process of elimination, I've determined that the existance of a Global.asax file is causing the problem. When I got into my test project and select "Add New Item" -> "Global Application Class", the request begin to queue. I have made no changes to the Global.asax.

Hi there, this is some kind of combined issue. -- It's about the session access. Strange ,right? What you can try is to set "enableSessionState="false|ReadOnly", the request is executed asyncronously. But as long as you change to true which is the default, your requests are piped up.

Note, the pipe-up behavior only happens for the requests from the same browser. If you have two browsers, it is always executed asyncronously.

The things that I haven't found out is where this crappy logic is. If you take a look at the system generated global.asax.cs , it is quite clean. I guess it is somewhere in HttpApplication which is the base class.

Hope this could help a bit.


Access to Session state variables must be performed synchronously. You can either set EnableSessionState to false or readonly, or you can use a different session state provider that allows asynchronous access to state variables.

No comments:

Post a Comment