ASP.NET 4.5 async-wait and Response.Redirect

Is there a way to redirect from Page_Load (or any other ASP.NET event) when using async - await ? Of course, Redirect throws a ThreadAbortException , but even if I catch it with try - catch , it ends up with an error. If I call Response("url", false) , this is not a failure, but I need to stop the page from executing (displaying the page, etc.) so that this is not a solution. And since I noticed that these two methods act differently:

This ends with a ThreadAbortException (I assume the task completes synchronously):

 protected async void Page_Load() { await Task.Run(() => { }); Response.Redirect("http://www.google.com/"); } 

This continues after Response.Redirect:

 protected async void Page_Load() { await Task.Delay(1000); Response.Redirect("http://www.google.com/"); } 

I have to wait for an answer, but I experimented, and even if I delete the await keyword (so that Task runs in the background and the method continues), it ends up the same. The only thing that helps is to remove the async - I thought async ONLY included await and nothing else ?!

+8
redirect asynchronous async-await
source share
2 answers

Well, I found the answer how to deal with it.

I created a wrapper for the Redirect method in the base class of the page:

 protected void Redirect(string url) { this.isRedirecting = true; Response.Redirect(url, false); if (Context.ApplicationInstance != null) Context.ApplicationInstance.CompleteRequest(); } 

And override Render and RaisePostBackEvent :

 protected override void Render(HtmlTextWriter writer) { if (this.isRedirecting) return; } protected override void RaisePostBackEvent(IPostBackEventHandler sourceControl, string eventArgument) { if (!this.isRedirecting) base.RaisePostBackEvent(sourceControl, eventArgument); } 

This is a trick. ASP.NET 4.5 does not PreRenderComplete event (= will not continue in the life cycle) until all expected tasks are complete.

+2
source share

Diclaimer: I did not use async / await , but the following is based on my reading of documents.

As I understand it, whenever you have await in your code, it will call the task provided asynchronously, and the rest of the method will actually be converted to a callback method. Therefore, in this case, since Page_Load is asynchronous, when it starts it, and it comes to wait, it will return control to the caller, waiting for the completion of its asynchronous task.

In the case of the Page_Load event, it seems to me that it will look as if it ended with time, the page life cycle will continue in the next step.

The reason for the differences is that in the first example, although it will continue with the life cycle, the callback will be almost immediate, so Response.Redirect will work almost immediately before the rest of the page can do anything.

In the case of the second, you have this delay of 1000, and during this time the page will continue to run other things, and only when this delay ends, respone.redirect is triggered. This can happen after the answer (due to an error) has already been started.

So essentially async includes await , but what await does seems to be a bit more than you expect.

+1
source share

All Articles