Why Response.Redirect causes System.Threading.ThreadAbortException?

前端 未结 10 1724
误落风尘
误落风尘 2020-11-22 15:00

When I use Response.Redirect(...) to redirect my form to a new page I get the error:

A first chance exception of type \'System.Threading.ThreadAbortEx

相关标签:
10条回答
  • 2020-11-22 15:26

    i even tryed to avoid this, just in case doing the Abort on the thread manually, but i rather leave it with the "CompleteRequest" and move on - my code has return commands after redirects anyway. So this can be done

    public static void Redirect(string VPathRedirect, global::System.Web.UI.Page Sender)
    {
        Sender.Response.Redirect(VPathRedirect, false);
        global::System.Web.UI.HttpContext.Current.ApplicationInstance.CompleteRequest();
    }
    
    0 讨论(0)
  • 2020-11-22 15:29

    The correct pattern is to call the Redirect overload with endResponse=false and make a call to tell the IIS pipeline that it should advance directly to the EndRequest stage once you return control:

    Response.Redirect(url, false);
    Context.ApplicationInstance.CompleteRequest();
    

    This blog post from Thomas Marquardt provides additional details, including how to handle the special case of redirecting inside an Application_Error handler.

    0 讨论(0)
  • 2020-11-22 15:37

    There is no simple and elegant solution to the Redirect problem in ASP.Net WebForms. You can choose between the Dirty solution and the Tedious solution

    Dirty: Response.Redirect(url) sends a redirect to the browser, and then throws a ThreadAbortedException to terminate the current thread. So no code is executed past the Redirect()-call. Downsides: It is bad practice and have performance implications to kill threads like this. Also, ThreadAbortedExceptions will show up in exception logging.

    Tedious: The recommended way is to call Response.Redirect(url, false) and then Context.ApplicationInstance.CompleteRequest() However, code execution will continue and the rest of the event handlers in the page lifecycle will still be executed. (E.g. if you perform the redirect in Page_Load, not only will the rest of the handler be executed, Page_PreRender and so on will also still be called - the rendered page will just not be sent to the browser. You can avoid the extra processing by e.g. setting a flag on the page, and then let subsequent event handlers check this flag before before doing any processing.

    (The documentation to CompleteRequest states that it "Causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution". This can easily be misunderstood. It does bypass further HTTP filters and modules, but it doesn't bypass further events in the current page lifecycle.)

    The deeper problem is that WebForms lacks a level of abstraction. When you are in a event handler, you are already in the process of building a page to output. Redirecting in an event handler is ugly because you are terminating a partially generated page in order to generate a different page. MVC does not have this problem since the control flow is separate from rendering views, so you can do a clean redirect by simply returning a RedirectAction in the controller, without generating a view.

    0 讨论(0)
  • 2020-11-22 15:37

    Response.Redirect() throws an exception to abort the current request.

    This KB article describes this behavior (also for the Request.End() and Server.Transfer() methods).

    For Response.Redirect() there exists an overload:

    Response.Redirect(String url, bool endResponse)
    

    If you pass endResponse=false, then the exception is not thrown (but the runtime will continue processing the current request).

    If endResponse=true (or if the other overload is used), the exception is thrown and the current request will immediately be terminated.

    0 讨论(0)
提交回复
热议问题