views:

74

answers:

5

In ASP.Net, I want to run some code (logging, other cleanup) after the page has already been sent to the user. I don't want this code to interfere with the amount of time it takes the client to receive a response. I tried placing this code in the OnUnload part of the page, but through testing (using breakpoints, or busy waiting loops) the client does not actually display the page until the code in the OnUnload is finished executing. Even though the response object is no longer available at this point, and therefore I would assume that the buffered response has been sent to the client, the client still does not display the page until the OnUnload is finished executing. The only way that seems to work at the moment is to start a new thread to do the work, and allow the OnUnload to finish immediately. However, I don't know if this is safe or not. Will the server kill the thread if it executes too long after the page is already sent out? Is there a more correct way to accomplish this?

+1  A: 

Unload is the last part of the ASP.NET page life cycle. See link below:

http://msdn.microsoft.com/en-us/library/ms178472.aspx

Is this something you could do with javascript or AJAX?

Abe Miessler
I specifically stated that I tried using the Unload section, and the browser still doesn't show the page until the unload code is done. This isn't something I could do in Javascript or Ajax, because it has to run server side, and I can't depend on the client having Javascript enabled for an AJAX call to be made to start the process up.
Kibbee
Kibbee I read that, but you didn't state that you knew that was the last stage in the page life cycle which is why I mentioned it. I don't think it deserves a -1 but i'll be sure not to post on any of your questions in the future if you're going to ding me for trying to help you understand how asp.net works.
Abe Miessler
Sorry, but I felt that the description of the downvote "This answer is not useful" really applied here. Personally, I find that if you aren't actually providing information that can solve the problem, that you should leave it as a comment. The answer you gave is just extra information. It doesn't provide a solution to the problem I'm having at all.
Kibbee
A: 

How about hooking into the page.Disposed event instead of the Unload event?

Shawn de Wet
Tried this out. Looks like while the page is sent before the code executes, the problem I now face is that it appears the code is not running at all. Although it may run in the future sometime, when the object itself is disposed of. I would like the code to be executed in a more timely fashion, not when it gets around to disposing the object.
Kibbee
A: 

Depending on what you need to do an ISAPI filter can be created to do stuff at the end of the response.

SargeATM
+1  A: 

Kibbee,

Try overriding the Page.Render method and flushing the response like so:

Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
    MyBase.Render(writer)

    Response.Flush() ' Sends all buffered output to the client

    ' Run some code after user gets their content
End Sub

I think at this point the response still isn't complete, but the user will get what the page has rendered before you finish running that final code.

HTH,

Mike

Mike C
This worked as expected. With the Repsonse object available I was able to get the browser to receive and render the content. However the problem is that the browser page still displayed as loading (rotating icon/hour glass) similar to when page is loading, even after the content had been received. This behaviour persisted, even after I added Response.Close after the Response.Flush(). Also nice to see somebody else who codes in VB.Net. Seems most of the .Net stuff around here focuses on C#.
Kibbee
I'm pretty sure that the response doesn't fully close until the entire ASP.net lifecycle finishes executing. This includes the HttpApplication.EndRequest event which AFIAK is the absolute last point in the lifecycle (Not counting when the application ends of course). I think that the above method is going to be the closest to what you want without spawning a new thread. If you go multi-threaded then I suggest spawning the thread in HttpApplication.EndRequest to avoid the thread being aborted on Response.End().
Mike C
A: 

You could try this solution - http://stackoverflow.com/questions/1424837/best-asp-net-background-service-implementation

Using a windows service and communicating with it through MSMQ might be a far more reliable solution and can scale up better. This will help you separate the concerns and let asp.net front end just focus on the user while the windows service focusses on the background tasks.

If you are moving to the cloud with azure, you can simply replace the asp.net front end with a web role and the windows service with a worker role and ur solution can scale seamlessly!

Roopesh Shenoy