Is there any way to redirect from Page_Load
(or any other ASP.NET event) when using async
-await
? Of course Redirect
throws ThreadAbortException
but even if I catch it with try
-catch
it ends up with an error page. If I call Response("url", false)
it doesn't crash but I need to stop execution of the page (rendering the page etc.) so it's not the solution. And as I noticed these two methods act differently:
This ends up with ThreadAbortException (I assume the task ends synchronously):
protected async void Page_Load()
{
await Task.Run(() => { });
Response.Redirect("http://www.google.com/");
}
This one continues after Response.Redirect:
protected async void Page_Load()
{
await Task.Delay(1000);
Response.Redirect("http://www.google.com/");
}
I must wait for the response but I was experimenting and even if I remove the await
keyword (so Task runs in background and the method continues) it ends up the same. Only thing that helps is to remove the async
keyword - I thought async
ONLY enables await
and nothing more?!
OK, I found the answer how to deal with it.
I've created a Redirect method wrapper in my base Page class:
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);
}
That does the trick. ASP.NET 4.5 won't fire the PreRenderComplete
event (= won't continue in the life-cycle) until all awaited tasks are completed.
Diclaimer: I've not used async
/await
but the following is based on my reading of the docs.
As I understand it whenever you have an await
in the code it will call the task provided aynchronously and the rest of the method is in effect converted into a callback method. So in this case because Page_Load
is async when it runs it and it comes to an await it will return control to the caller while waiting for its aynchronous task to complete.
In the case of the Page_Load
event this will, I think, then appear as if it has completed sopresumably the page life cycle will continue onto its next step.
The reason for the differences is that in your first example although it will continue on with the life cycle the callback is almost immediate so the Response.Redirect
will run almost immediately, before the rest of the page has a chance to do anything.
In the case of the second one you have that delay of 1000 and during that time the page will continue running other things and its only when that delay is over that the respone.redirect fires. This might be after a response (from an error) has already been fired.
So in essence async
does enable await
but what await
does sounds like it is a bit more than you expect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With