Failure with Nested WebForm Callbacks

Posted by Matt | Filed under , ,

I am working on an ASP.NET application that requires some WebForm callbacks.  However, I am running into the following error:

Microsoft JScript runtime error: '__pendingCallbacks[...].async' is null or not an object

This error appears in the code below.

function WebForm_CallbackComplete() {
  for (var i = 0; i < __pendingCallbacks.length; i++) {
    callbackObject = __pendingCallbacks[i];
    if (callbackObject && callbackObject.xmlRequest && 
        (callbackObject.xmlRequest.readyState == 4)) {
      WebForm_ExecuteCallback(callbackObject);
      if (!__pendingCallbacks[i].async) {
        __synchronousCallBackIndex = -1;
      }
      __pendingCallbacks[i] = null;
      var callbackFrameID = "__CALLBACKFRAME" + i;
      var xmlRequestFrame = document.getElementById(callbackFrameID);
      if (xmlRequestFrame) {
        xmlRequestFrame.parentNode.removeChild(xmlRequestFrame);
      }
    }
  }
}

After doing some Googling, I found out that there was a previously common problem with this same line of code. The previous error had a scope issue with the variable 'i'.  However, when using Visual Studio 2008, and as you see above, this scope issue is fixed by adding ‘var’ in the for loop.

So what’s the issue now?

It appears to be an issue of calling a web callback synchronously from within the end callback of a previous web callback.  Essentially, I am nesting WebForm callbacks:  calling a second before the first is 100% complete.

Here’s what is happening.  I’m calling ‘WebForm_DoCallback’ from my Javascript and that’s going to the web server and returning.  When it returns, Microsoft’s system calls my end-of-callback event callback.  In this function, I am calling ‘WebForm_DoCallback’ again.  It looks like Microsoft’s synchronous callback system does not like nested callbacks.  The second call is destroying the __pendingCallbacks array before the first call completes.

I was able to avoid the issue by doing the following:

var __data = null;
function End_Callback_Proxy(arg, context) {
  __data = arg;
  window.setTimeout('End_Callback_Helper()', 0);
}
function End_Callback_Helper() {
  End_Callback(__data, 'ResetMarker');
}

Here, I set the event callback to be ‘End_Callback_Proxy’ instead of ‘End_Callback’.  This saves the data from the callback to a variable, and tells the window to call ‘End_Callback_Helper’ a little bit later.  This allows the current callback to complete before the next one is called.

I have submitted this issue to Microsoft Connect.  You can view the issue here.

Comments

June 27, 2009 12:41

how to play the casino craps

Fantastic tip! I had been trying to figure this out for ages.Now, if I could just find a way to make controls on the "BigMaster" page "Public" so I could access them directly without having to create properties.. ;)

how to play the casino craps

Comments are closed