473,395 Members | 1,936 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Async callbacks with Global.asax

A strange behaviour thatI found in ASP.NET 2.0.

I am trying to issue a callback request (handled by
ICallbackEventHandler and RaiseCallbackEvent) and a regular GET request
in the client browser and handle them at the same time - in parallel.

The funny thing is that the behaviour of the implementation I created
depends on the existence of Global.asax in the Web application.

Here is the source of the page that handles the regular GET request.

public partial class _Default : System.Web.UI.Page,
ICallbackEventHandler
{
protected void Page_Load(object sender, EventArgs e)
{
this.ClientScript.RegisterStartupScript(this.GetTy pe(),
"ClientCallback", "<script type=\"text/javascript\">function
ClientCallback() { };</script>");

Button button = new Button();
button.Text = "Click";
button.UseSubmitBehavior = false;
string callbackcall =
ClientScript.GetCallbackEventReference(this, "", "ClientCallback", "",
false);
button.OnClientClick = "javascript:
window.location='Download.aspx'; " + callbackcall + "; return false;";
PlaceHolder1.Controls.Add(button);
}

public void RaiseCallbackEvent(string eventArgument)
{
FileStream file = new FileStream("c:\\test.bin",
FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite);
StreamWriter writer = new StreamWriter(file);
writer.WriteLine("dummy text data");
writer.Close();
}

public string GetCallbackResult()
{
return "";
}
}
And here is the page that handles the callback request.

public partial class Download : Page
{
protected delegate void AsyncTaskDelegate();

private byte[] fileData = null;
private AsyncTaskDelegate dlgt = null;

protected void Page_Load(object sender, EventArgs e)
{
PageAsyncTask getPdfData = new PageAsyncTask(new
BeginEventHandler(this.BeginGetData), new
EndEventHandler(this.EndGetData), new
EndEventHandler(this.TimeoutGetData), null, true);
Page.RegisterAsyncTask(getPdfData);
Page.ExecuteRegisteredAsyncTasks();
}

private void TimeoutGetData(IAsyncResult ar)
{
dlgt.EndInvoke(ar);
}

private void EndGetData(IAsyncResult ar)
{
dlgt.EndInvoke(ar);
}

private IAsyncResult BeginGetData(object sender, EventArgs e,
AsyncCallback cb, object extraData)
{
dlgt = new AsyncTaskDelegate(this.ExecuteGetData);
IAsyncResult result = dlgt.BeginInvoke(cb, extraData);
return result;
}

private void ExecuteGetData()
{
for (int i = 0; i < 10; i++)
{
if (!File.Exists("c:\\test.bin"))
{
Thread.Sleep(2000);
continue;
}

FileStream file = new FileStream("c:\\test.bin",
FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
fileData = new byte[file.Length];
file.Read(fileData, 0, fileData.Length);
file.Close();
}
}

protected override void Render(HtmlTextWriter writer)
{
if (this.fileData == null) return;

Response.Clear();

Response.ContentType = "application/download";

Response.AddHeader("Content-Disposition", "attachment;
filename=test.bin");

Response.OutputStream.Write(this.fileData, 0,
this.fileData.Length);
Response.End();
}
}

The code above is quite obvious. The _Default page creates a button
with onclick JavaScript handler that creates GET request using the the
window.location and a callback using the standard ASP.NET mechanism.
When the GET request gets handled in Download page it prepares data for
the callback handler in _Default page.

As I formentioned, when there is no Global.asax in the web application,
the code works as one would expect. However, when I create a new
Global.asax in the web application (and leave it empty), the code
breaks.

With Global.asax, I never achieved both requests to be handled at the
same time - in parallel. They are handled one after the other - first
the GET in Download - after it "timeouts" and the handlers exit, the
callback handler in _Default gets executed.

I took two callstack snapshots - both in the Raisecallback handler of
the _Default page. First snapshot with the Global.asax in the web
application and the second without.

With Global.asax:
App_Web_kizvwxal.dll!_Default.RaiseCallbackEvent(s tring eventArgument = "") Line 39 C# System.Web.dll!System.Web.UI.Page.PrepareCallback( string
callbackControlID = "__Page") + 0xbb bytes
System.Web.dll!System.Web.UI.Page.ProcessRequestMa in(bool
includeStagesBeforeAsyncPoint = true, bool includeStagesAfterAsyncPoint
= true) + 0x1085 bytes
System.Web.dll!System.Web.UI.Page.ProcessRequest(b ool
includeStagesBeforeAsyncPoint = true, bool includeStagesAfterAsyncPoint
= true) + 0x70 bytes
System.Web.dll!System.Web.UI.Page.ProcessRequest() + 0x71 bytes

System.Web.dll!System.Web.UI.Page.ProcessRequestWi thNoAssert(System.Web.HttpContext
context = {System.Web.HttpContext}) + 0x26 bytes

System.Web.dll!System.Web.UI.Page.ProcessRequest(S ystem.Web.HttpContext
context = {System.Web.HttpContext}) + 0x88 bytes

App_Web_kizvwxal.dll!ASP.default_aspx.ProcessReque st(System.Web.HttpContext
context = {System.Web.HttpContext}) + 0x30 bytes C#

System.Web.dll!System.Web.HttpApplication.CallHand lerExecutionStep.System.Web.HttpApplication.IExecu tionStep.Execute()
+ 0x192 bytes

System.Web.dll!System.Web.HttpApplication.ExecuteS tep(System.Web.HttpApplication.IExecutionStep
step = {System.Web.HttpApplication.CallHandlerExecutionSt ep}, ref bool
completedSynchronously = true) + 0x76 bytes

System.Web.dll!System.Web.HttpApplication.ResumeSt eps(System.Exception
error = null) + 0x1c6 bytes

System.Web.dll!System.Web.HttpApplication.ResumeSt epsFromThreadPoolThread(System.Exception
error = null) + 0x34 bytes

System.Web.dll!System.Web.HttpApplication.AsyncEve ntExecutionStep.ResumeStepsWithAssert(System.Excep tion
error = null) + 0x37 bytes

System.Web.dll!System.Web.HttpApplication.AsyncEve ntExecutionStep.OnAsyncEventCompletion(System.IAsy ncResult
ar = {System.Web.HttpAsyncResult}) + 0xbf bytes
System.Web.dll!System.Web.HttpAsyncResult.Complete (bool synchronous =
false, object result = null, System.Exception error = null) + 0x46
bytes

System.Web.dll!System.Web.SessionState.SessionStat eModule.PollLockedSessionCallback(object
state = 1) + 0x18b bytes

mscorlib.dll!System.Threading._TimerCallback.Timer Callback_Context(object
state) + 0x1a bytes
mscorlib.dll!System.Threading.ExecutionContext.run TryCode(object
userData) + 0x43 bytes
[Native to Managed Transition]
[Managed to Native Transition]

mscorlib.dll!System.Threading.ExecutionContext.Run Internal(System.Threading.ExecutionContext
executionContext, System.Threading.ContextCallback callback, object
state) + 0xa7 bytes

mscorlib.dll!System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext
executionContext, System.Threading.ContextCallback callback, object
state) + 0x92 bytes

mscorlib.dll!System.Threading._TimerCallback.Perfo rmTimerCallback(object
state) + 0x5b bytes
[Appdomain Transition]
Without Global.asax: App_Web_vv-y2doi.dll!_Default.RaiseCallbackEvent(string eventArgument = "") Line 39 C#

System.Web.dll!System.Web.UI.Page.PrepareCallback( string
callbackControlID = "__Page") + 0xbb bytes
System.Web.dll!System.Web.UI.Page.ProcessRequestMa in(bool
includeStagesBeforeAsyncPoint = true, bool includeStagesAfterAsyncPoint
= true) + 0x1086 bytes
System.Web.dll!System.Web.UI.Page.ProcessRequest(b ool
includeStagesBeforeAsyncPoint = true, bool includeStagesAfterAsyncPoint
= true) + 0x70 bytes
System.Web.dll!System.Web.UI.Page.ProcessRequest() + 0x71 bytes

System.Web.dll!System.Web.UI.Page.ProcessRequestWi thNoAssert(System.Web.HttpContext
context = {System.Web.HttpContext}) + 0x26 bytes

System.Web.dll!System.Web.UI.Page.ProcessRequest(S ystem.Web.HttpContext
context = {System.Web.HttpContext}) + 0x88 bytes

App_Web_vv-y2doi.dll!ASP.default_aspx.ProcessRequest(System.W eb.HttpContext
context = {System.Web.HttpContext}) + 0x30 bytes C#

System.Web.dll!System.Web.HttpApplication.CallHand lerExecutionStep.System.Web.HttpApplication.IExecu tionStep.Execute()
+ 0x192 bytes

System.Web.dll!System.Web.HttpApplication.ExecuteS tep(System.Web.HttpApplication.IExecutionStep
step = {System.Web.HttpApplication.CallHandlerExecutionSt ep}, ref bool
completedSynchronously = true) + 0x76 bytes

System.Web.dll!System.Web.HttpApplication.ResumeSt eps(System.Exception
error = null) + 0x1c6 bytes

System.Web.dll!System.Web.HttpApplication.System.W eb.IHttpAsyncHandler.BeginProcessRequest(System.We b.HttpContext
context = {System.Web.HttpContext}, System.AsyncCallback cb =
{System.AsyncCallback}, object extraData = {System.Web.HttpContext}) +
0xa1 bytes

System.Web.dll!System.Web.HttpRuntime.ProcessReque stInternal(System.Web.HttpWorkerRequest
wr = {Microsoft.VisualStudio.WebHost.Request}) + 0x1aa bytes

System.Web.dll!System.Web.HttpRuntime.ProcessReque stNow(System.Web.HttpWorkerRequest
wr = {Microsoft.VisualStudio.WebHost.Request}) + 0x21 bytes

System.Web.dll!System.Web.HttpRuntime.ProcessReque stNoDemand(System.Web.HttpWorkerRequest
wr = {Microsoft.VisualStudio.WebHost.Request}) + 0x51 bytes

System.Web.dll!System.Web.HttpRuntime.ProcessReque st(System.Web.HttpWorkerRequest
wr = {Microsoft.VisualStudio.WebHost.Request}) + 0x63 bytes
WebDev.WebHost.dll!Microsoft.VisualStudio.WebHost. Request.Process() +
0x114 bytes

WebDev.WebHost.dll!Microsoft.VisualStudio.WebHost. Host.ProcessRequest(Microsoft.VisualStudio.WebHost .Connection
conn = {System.Runtime.Remoting.Proxies.__TransparentProx y}) + 0x5c
bytes
[Appdomain Transition]

WebDev.WebHost.dll!Microsoft.VisualStudio.WebHost. Server.OnSocketAccept(object
acceptedSocket) + 0x86 bytes

mscorlib.dll!System.Threading._ThreadPoolWaitCallb ack.WaitCallback_Context(object
state) + 0x2f bytes

mscorlib.dll!System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext
executionContext, System.Threading.ContextCallback callback, object
state) + 0x81 bytes

mscorlib.dll!System.Threading._ThreadPoolWaitCallb ack.PerformWaitCallback(object
state) + 0x6c bytes

It boils down that the problem is caused by a colision of the mechanism
ASP.NET uses when dispatching requests in web applicatons with
Global.asax and the asynchronous tasks used in the Download handlers.
Note that when the asynchronous task mechanism is not used in the
Download page, everything works flawlessly.
There it is I got so far. If anyone had any ideas I would really
appreciate it.

Hynek

Jun 14 '06 #1
0 2409

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

22
by: fd123456 | last post by:
Hi Tom ! Sorry about the messy quoting, Google is playing tricks on me at the moment. > Global.asax is where you normally have the Global Application > and Session variables and code to...
12
by: John M | last post by:
Hello, On Microsoft Visual Studio .NET 2003, I want to use some global elements, that can be used in each one of my pages. i.e I put a oleDBConnection on global.asax.vb How can I use it...
8
by: Vishwanathan Raman | last post by:
Hi I have a declared a static DataSet object SOBJ in Global.asax.I also have a localy defined DataSet LSOBJ in Global.asax which I am storing in Application State.Is there any technical...
5
by: ad | last post by:
The Global.asax is code-inside with default. How to change Global.asax to code-behind?
11
by: Ron | last post by:
I have a web project compiled with the new "Web Deployment Projects" plugin for VS2005. I'm deploying the web project to one assembly and with updateable option set to ON. When I'm running the...
6
by: Shak | last post by:
Hi all, Three questions really: 1) The async call to the networkstream's endread() (or even endxxx() in general) blocks. Async calls are made on the threadpool - aren't we advised not to...
16
by: thefritz_j | last post by:
We just converted our VS2003 1.1 VB web project (which was working fine) to VS2005 2.0 and now I get: Parser Error Message: Could not load type '<Namespace>.'. Source Error: Line 1: <%@...
8
by: Rob T | last post by:
When I was using VS2003, I was able to compile my asp.net project locally on my machine and copy it to the production server and it would run just fine. I've now converted to VS2005. The project...
15
by: =?Utf-8?B?UGF0Qg==?= | last post by:
Just starting to move to ASP.NET 2.0 and having trouble with the Global.asax code file. In 1.1 I could have a code behind file for the global.asax file. This allow for shared variables of the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.