[.net] Response.End ()가 유해한 것으로 간주됩니까?

이 KB 기사 는 ASP.NET이Response.End() 이 스레드를 중단 .

리플렉터는 다음과 같이 보입니다.

public void End()
{
    if (this._context.IsInCancellablePeriod)
    {
        InternalSecurityPermissions.ControlThread.Assert();
        Thread.CurrentThread.Abort(new HttpApplication.CancelModuleException(false));
    }
    else if (!this._flushing)
    {
        this.Flush();
        this._ended = true;
        if (this._context.ApplicationInstance != null)
        {
            this._context.ApplicationInstance.CompleteRequest();
        }
    }
}

이것은 나에게 매우 가혹한 것 같습니다. KB 기사에서 알 수 있듯이 다음 앱의 코드는 Response.End()실행되지 않으며 놀랍게도 최소화하는 원칙을 위반합니다. Application.Exit()WinForms 앱 과 거의 같습니다 . 에 의한 스레드 중단 예외 Response.End()는 포착 할 수 없으므로 코드를 둘러싼 tryfinally만족하지 않습니다.

항상 피해야하는지 궁금합니다 Response.End().

Response.End()언제 Response.Close(), 언제 , 언제 사용해야하는지 제안 할 수 있습니까 HttpContext.Current.ApplicationInstance.CompleteRequest()?

ref : Rick Strahl의 블로그 항목 .


내가받은 입력을 기반으로 내 대답은 Response.End입니다. 유해 하지만 일부 경우에 유용합니다.

  • 예외적 인 상황에서 Response.End()즉시 종료하려면 잡을 수없는 던지기로 사용하십시오 HttpResponse. 디버깅 중에도 유용 할 수 있습니다. 일상적인 반응을 피하십시오Response.End() .
  • Response.Close()클라이언트와의 연결을 즉시 닫는 데 사용 합니다. 당 이 MSDN 블로그 게시물 이 방법은 보통의 HTTP 요청을 처리하기위한 것이 아닙니다. 이 메소드를 호출 할만한 이유가있을 가능성은 거의 없습니다.
  • CompleteRequest()정상적인 요청을 끝내는 데 사용 합니다. 현재 이벤트가 완료된 후 CompleteRequestASP.NET 파이프 라인이 이벤트로 이동합니다. 따라서 호출 한 다음 응답에 더 많은 것을 쓰면 쓰기가 클라이언트로 전송됩니다.EndRequestHttpApplicationCompleteRequest

편집-2011 년 4 월 13 일

또한 선명도는 여기에 있습니다 :
MSDN 블로그에 유용한 포스트
존 리드하여 유용한 분석



답변

앱에서 예외 로거를 사용했다면 ThreadAbortException이 양성 의 s 로 물을 뿌릴 것입니다Response.End() 전화 입니다. 나는 이것이 “노크 오프!”라고 말하는 Microsoft의 방식이라고 생각합니다.

Response.End()예외적 인 조건이 있고 다른 조치가 불가능한 경우 에만 사용 합니다. 아마도이 예외를 기록하면 실제로 경고가 표시 될 수 있습니다.


답변

TL; DR

처음에는 [Response.End]에 대한 모든 호출을 […] CompleteRequest () 호출로 간단히 바꾸어야했지만 포스트 백 처리 및 html 렌더링을 피하려면 [.. .]도 무시됩니다.

Jon Reid , “최종 분석”


MSDN, Jon Reid 및 Alain Renon에 따라 :

ASP.NET 성능-예외 관리-예외를 피하는 코드 작성

Server.Transfer, Response.Redirect, Response.End 메소드는 모두 예외를 발생시킵니다. 이러한 각 메서드는 내부적으로 Response.End를 호출합니다. Response.End를 호출 하면 ThreadAbortException 예외가 발생 합니다.

ThreadAbortException 솔루션

HttpApplication.CompleteRequest ()는 페이지 이벤트 체인이 아니라 애플리케이션 이벤트 체인이 아닌 HttpApplication 이벤트 파이프 라인 [-]에서 스레드가 대부분의 이벤트를 건너 뛰도록하는 변수를 설정합니다.

이벤트를 처리하거나 페이지를 렌더링하기 전에 페이지를 종료해야하는지 플래그를 지정하는 클래스 레벨 변수를 작성하십시오. […] RaisePostBackEvent 및 Render 메소드를 재정의하는 것이 좋습니다.

성능이 중요한 경우 정상적인 요청 처리에 Response.End 및 Response.Close가 사용되지 않습니다. Response.End는 관련 성능 저하로 요청 처리를 종료 할 수있는 편리한 방법입니다. Response.Close는 IIS / 소켓 수준에서 HTTP 응답을 즉시 종료하기위한 것으로 KeepAlive와 같은 문제가 발생합니다.

ASP.NET 요청을 종료하는 데 권장되는 방법은 HttpApplication.CompleteRequest입니다. HttpApplication.CompleteRequest는 ASP.NET 페이지 파이프 라인 (앱 파이프 라인의 한 단계)이 아니라 나머지 IIS / ASP.NET 응용 프로그램 파이프 라인을 건너 뛰므로 ASP.NET 렌더링은 수동으로 건너 뛰어야합니다.


암호

내가 말할 수있는 최선의 방법으로 Copyright © 2001-2007, C6 Software, Inc.


참고

HttpApplication.CompleteRequest

ASP.NET이 HTTP 파이프 라인 실행 체인에서 모든 이벤트와 필터링을 무시하고 EndRequest 이벤트를 직접 실행합니다.

응답. 종료

이 방법은 ASP와의 호환성 , 즉 ASP.NET.preceded ASP.NET보다 선행 된 COM 기반 웹 프로그래밍 기술과의 호환성을 위해서만 제공됩니다 . [엠파 시스 추가]

응답. 닫기

이 메소드는 갑작스러운 방식으로 클라이언트와의 연결을 종료하며 정상적인 HTTP 요청 처리를위한 것은
아닙니다 . [엠파 시스 추가]


답변

이 질문은 모든 Google 검색의 상단 근처에 response.end에 대한 정보를 표시하므로 전체 ASPX 페이지를 렌더링하지 않고 이벤트에 대한 응답으로 CSV / XML / PDF 등을 게시하려는 저와 같은 다른 검색의 경우이 방법입니다. . (렌더 메소드를 재정의하는 것은 그러한 간단한 작업 IMO에 대해 지나치게 복잡합니다)

// Add headers for a csv file or whatever
Response.ContentType = "text/csv"
Response.AddHeader("Content-Disposition", "attachment;filename=report.csv")
Response.AddHeader("Pragma", "no-cache")
Response.AddHeader("Cache-Control", "no-cache")

// Write the data as binary from a unicode string
Dim buffer As Byte()
buffer = System.Text.Encoding.Unicode.GetBytes(csv)
Response.BinaryWrite(buffer)

// Sends the response buffer
Response.Flush()

// Prevents any other content from being sent to the browser
Response.SuppressContent = True

// Directs the thread to finish, bypassing additional processing
HttpContext.Current.ApplicationInstance.CompleteRequest()


답변

“여전히 Response.Close와 CompleteRequest ()의 차이점을 모르겠습니다”라는 질문에 대해 다음과 같이 말합니다.

CompleteRequest ()를 선호하고 Response.Close ()를 사용하지 마십시오.

참고 항목 다음 문서를이 사례를 잘 요약 한 를 .

CompleteRequest ()를 호출 한 후에도 일부 텍스트 (예 : ASPX 코드에서 다시 작성)가 응답 출력 스트림에 추가됩니다. 다음 문서에 설명 된대로 Render 및 RaisePostBackEvent 메서드를 재정 의하여이를 방지 할 수 있습니다. .

BTW : 특히 파일 다운로드를 에뮬레이트하기 위해 http 스트림에 데이터를 쓸 때 Response.End () 사용을 방지하는 데 동의합니다. 로그 파일이 ThreadAbortExceptions로 가득 찰 때까지 과거에 Response.End ()를 사용했습니다.


답변

Response.End는 유해합니다 “라는 문구에 동의하지 않습니다 . 확실히 해롭지 않습니다. Response.End는 말하는 것을 수행합니다. 페이지 실행을 종료합니다. 리플렉터를 사용하여 구현 방식을 확인하는 것은 유익한 것으로 간주해야합니다.


제어 흐름으로 사용 하는 2cent Recommendation
AVOIDResponse.End() .
DO의 사용은 Response.End()당신이 요청 실행을 중지하고 (일반적으로) * 어떤 코드가 그 지점을지나 실행되지된다는 점에 유의해야합니다.


* Response.End()ThreadAbortException이 의.

Response.End() 현재 구현의 일부로 ThreadAbortException을 throw합니다 (OP에서 명시한대로).

ThreadAbortException은 catch 할 수있는 특수 예외이지만 catch 블록 끝에서 자동으로 다시 발생합니다.

ThreadAbortExceptions를 처리해야하는 코드를 작성하는 방법을 보려면 @Mehrdad의 SO에 대한 응답을 참조하십시오. RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup 메소드 를 참조 하는 finally 블록 에서 threadabortexception을 감지하는 방법 제한된 실행 영역


릭 Strahl 기사 언급은 유익하고, 확인뿐만 아니라 주석을 읽을 수 있도록. Strahl의 문제는 구체적입니다. 그는 데이터를 클라이언트 (이미지)로 가져 와서 이미지 제공 속도를 늦추지 않는 적중 추적 데이터베이스 업데이트를 처리하려고했기 때문에 Response.End가 호출 된 후 무언가를 수행하는 데 문제가있었습니다.


답변

프로그램 흐름을 제어하기 위해 Response.End () 사용을 고려한 적이 없습니다.

그러나 Response.End ()는 예를 들어 파일을 사용자에게 제공 할 때 유용 할 수 있습니다.

응답에 파일을 작성했으며 파일이 손상 될 수 있으므로 응답에 다른 항목을 추가하지 않으려 고합니다.


답변

.NET과 Classic ASP에서 Response.End ()를 사용하여 이전에 강제로 종료했습니다. 예를 들어, certian에 많은 로그인 시도가있을 때 사용합니다. 또는 인증되지 않은 로그인으로 보안 페이지에 액세스하는 경우 (예 🙂

    if (userName == "")
    {
        Response.Redirect("......");
        Response.End();
    }
    else
    {
      .....

사용자에게 파일을 제공 할 때 Flush를 사용하면 End로 인해 문제가 발생할 수 있습니다.