c# - Response.Redirect가 System.Threading.ThreadAbortException을 발생시키는 이유는 무엇입니까?




asp.net .net-3.5 (7)

ASP.Net WebForms의 Redirect 문제에 대한 간단하고 우아한 해결책은 없습니다 . Dirty 솔루션과 Tedious 솔루션 중에서 선택할 수 있습니다.

Dirty : Response.Redirect(url) 은 브라우저로 리디렉션을 보내고 ThreadAbortedException 을 throw하여 현재 스레드를 종료합니다. 따라서 코드는 Redirect () 호출을 지나서 실행되지 않습니다. 단점 :이 같은 스레드를 죽이는 것은 나쁜 습관이고 성능에 영향을 미칩니다. 또한 예외 로깅에서 ThreadAbortedExceptions 가 표시됩니다.

지루한 질문 : Response.Redirect(url, false) 를 호출 한 다음 Context.ApplicationInstance.CompleteRequest() 를 호출하는 것이 좋습니다. 그러나 코드 실행은 계속되고 페이지 수명주기의 나머지 이벤트 핸들러는 여전히 실행됩니다. 예를 들어 Page_Load에서 리디렉션을 수행하면 나머지 핸들러가 실행될뿐만 아니라 Page_PreRender 등도 호출되며 렌더링 된 페이지는 브라우저로 전송되지 않습니다. 예를 들어 페이지에 플래그를 설정 한 다음 후속 이벤트 핸들러가 처리를 수행하기 전에이 플래그를 확인하도록 할 수 있습니다.

( CompleteRequest 대한 문서에 " ASP.NET이 모든 이벤트를 우회하여 실행의 HTTP 파이프 라인 체인에서 필터링됩니다 ."이것은 쉽게 오해 될 수 있으며 추가 HTTP 필터와 모듈을 우회하지만 더 이상 무시하지 않습니다. 현재 페이지 수명주기의 이벤트

더 심각한 문제는 WebForms에 추상 수준이 없다는 것입니다. 이벤트 핸들러에 있으면 이미 출력 할 페이지를 작성하는 중입니다. 다른 페이지를 생성하기 위해 부분적으로 생성 된 페이지를 종료하기 때문에 이벤트 핸들러에서 리디렉션하는 것은 추악합니다. MVC는 컨트롤 흐름이 렌더링보기와 분리되어 있기 때문에이 문제가 발생하지 않으므로보기를 생성하지 않고 컨트롤러에서 RedirectAction 을 반환하기 만하면 깨끗한 리디렉션을 수행 할 수 있습니다.

Response.Redirect (...)를 사용하여 내 양식을 새 페이지로 리디렉션하면 오류가 발생합니다.

mscorlib.dll에서 'System.Threading.ThreadAbortException'유형의 첫 번째 예외가 발생했습니다.
mscorlib.dll에서 'System.Threading.ThreadAbortException'유형의 예외가 발생했지만 사용자 코드에서 처리되지 않았습니다.

이것에 대한 나의 이해는 웹 서버가 response.redirect가 호출 된 페이지의 나머지 부분을 중단함으로써 오류가 발생한다는 것입니다.

endResponse라는 Response.Redirect 두 번째 매개 변수를 추가 할 수 있다는 것을 알고 있습니다. endResponse를 True로 설정하면 여전히 오류가 발생하지만 False로 설정하면 오류가 발생합니다. 나는 웹 서버가 내가 리디렉션 된 페이지의 나머지 부분을 실행하고 있다는 것을 의미하지만 꽤 확신한다. 최소한을 말하면 비효율적 인 것처럼 보일 것입니다. 이 작업을 수행하는 더 좋은 방법이 있습니까? Response.Redirect 이외의 것이거나 이전 페이지에서 ThreadAbortException 얻지 못할 곳을 강제로로드하는 방법이 있습니까?


나도 그 문제가 있었다. Response.Redirect 대신 Server.Transfer를 사용해보십시오. 나를 위해 일했습니다.


내가하는 일은 다른 예외와 함께이 예외를 잡는 것입니다. 희망이 도움이 누군가.

 catch (ThreadAbortException ex1)
 {
    // do nothing
 }
 catch(Exception ex)
 {
     writeToLog(ex.Message);
 }

또한 다른 솔루션을 시도했지만 리디렉션 후에 코드 일부가 실행되었습니다.

public static void ResponseRedirect(HttpResponse iResponse, string iUrl)
    {
        ResponseRedirect(iResponse, iUrl, HttpContext.Current);
    }

    public static void ResponseRedirect(HttpResponse iResponse, string iUrl, HttpContext iContext)
    {
        iResponse.Redirect(iUrl, false);

        iContext.ApplicationInstance.CompleteRequest();

        iResponse.BufferOutput = true;
        iResponse.Flush();
        iResponse.Close();
    }

따라서 리디렉션 후 코드 실행을 방지해야하는 경우

try
{
   //other code
   Response.Redirect("")
  // code not to be executed
}
catch(ThreadAbortException){}//do there id nothing here
catch(Exception ex)
{
  //Logging
}

심지어 경우에 수동으로 스레드에서 중단 작업을 피하기 위해 tryed 있지만 오히려 "CompleteRequest"함께 이동하고 이동 - 내 코드가 리디렉션 어쨌든 반환 명령이 있습니다. 이렇게 할 수 있습니다.

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();
}

올바른 패턴은 endResponse = false로 리디렉션 오버로드를 호출하고 IIS 파이프 라인에 컨트롤을 반환하면 EndRequest 스테이지로 직접 이동해야한다는 호출을하는 것입니다.

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

Thomas Marquardt 의이 블로그 게시물 은 Application_Error 핸들러에서 리디렉션하는 특별한 경우를 처리하는 방법을 포함하여 추가 세부 정보를 제공합니다.


Response.Redirect() 는 현재 요청을 중단하는 예외를 throw합니다.

이 기술 자료 문서에서는 Request.End()Server.Transfer() 메서드에 Server.Transfer() 동작을 설명합니다.

Response.Redirect() 에는 과부하가 있습니다.

Response.Redirect(String url, bool endResponse)

endResponse = false 를 전달하면 예외가 발생하지 않지만 런타임은 현재 요청을 계속 처리합니다.

endResponse = true (또는 다른 오버로드가 사용 된 경우) 예외가 발생하고 현재 요청이 즉시 종료됩니다.





.net-3.5