[c#] Excel 파일 다운로드 중 Response.End () “스레드가 중단되었습니다”예외를 방지하는 방법

내 데이터 세트를 Excel로 변환하고 해당 Excel을 다운로드하려고했습니다. 필요한 Excel 파일을 얻었지만 System.Threading.ThreadAbortException이 모든 Excel 다운로드에서 발생했습니다. 이 문제를 해결하는 방법? .. 도와주세요 …

내 aspx 화면에서이 메서드를 호출합니다.이 메서드에서 동일한 예외가 발생했습니다.

많은 aspx 화면에서 public void ExportDataSet (DataSet ds) 함수를 호출하고 런타임시 발생하는 예외에 대한 오류 로거 메서드를 유지 관리하고 있습니다. 해당 예외가 .txt 파일에 기록됩니다. 따라서 동일한 예외가 모든 aspx 화면의 txt 파일에 기록됩니다. 메서드 선언 클래스 파일에서 aspx로 예외가 발생하는 것을 방지하고 싶습니다. 단순히 메서드 선언 클래스 파일 자체에서이 예외를 처리하고 싶습니다.

ASPX 파일 메서드 호출 : excel.ExportDataSet (dsExcel);

방법 정의 :

public void ExportDataSet(DataSet ds)
{

   try
   {
      string filename = "ExcelFile.xls";
      HttpResponse response = HttpContext.Current.Response;
      response.Clear();
      response.Charset = "";
      response.ContentType = "application/vnd.ms-excel";
      response.AddHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
      using (StringWriter sw = new StringWriter())
      {
         using (HtmlTextWriter htw = new HtmlTextWriter(sw))
         {
             GridView dg = new GridView();
             dg.DataSource = ds.Tables[0];
             dg.DataBind();
             dg.RenderControl(htw);
             // response.Write(style);
             response.Write(sw.ToString());
             response.End();                    // Exception was Raised at here
         }
      }
   }
   catch (Exception ex)
   {
      string Err = ex.Message.ToString();
      EsHelper.EsADLogger("HOQCMgmt.aspx ibtnExcelAll_Click()", ex.Message.ToString());
   }
   finally
   {
   }
}



답변

온라인으로 조사한 결과 Response.End() 항상 예외가 발생 .

이것을 교체하십시오 : HttpContext.Current.Response.End();

이것으로 :

HttpContext.Current.Response.Flush(); // Sends all currently buffered output to the client.
HttpContext.Current.Response.SuppressContent = true;  // Gets or sets a value indicating whether to send HTTP content to the client.
HttpContext.Current.ApplicationInstance.CompleteRequest(); // Causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution and directly execute the EndRequest event.


답변

이것은 제가 Thread was being aborted예외 를 처리하는 데 도움이되었습니다 .

try
{
   //Write HTTP output
    HttpContext.Current.Response.Write(Data);
}
catch (Exception exc) {}
finally {
   try
    {
      //stop processing the script and return the current result
      HttpContext.Current.Response.End();
     }
   catch (Exception ex) {}
   finally {
        //Sends the response buffer
        HttpContext.Current.Response.Flush();
        // Prevents any other content from being sent to the browser
        HttpContext.Current.Response.SuppressContent = true;
        //Directs the thread to finish, bypassing additional processing
        HttpContext.Current.ApplicationInstance.CompleteRequest();
        //Suspends the current thread
        Thread.Sleep(1);
     }
   }

대신 다음 코드를 사용 HttpContext.Current.Response.End()하면 Server cannot append header after HTTP headers have been sent예외 가 발생합니다.

            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.SuppressContent = True;
            HttpContext.Current.ApplicationInstance.CompleteRequest();

도움이되기를 바랍니다.


답변

다음과 같은 질문으로 보입니다.

ASP.NET System.Web.HttpResponse.End ()가 호출되면 현재 스레드가 중단됩니까?

그래서 그것은 의도적으로 설계된 것입니다. 해당 예외에 대한 catch를 추가하고 우아하게 “무시”해야합니다.


답변

Response.End ()를 Try / Catch 및 Using 블록 외부로 이동합니다.

나머지 요청을 우회하기 위해 Exception을 던진다 고 가정하고, 당신은 그것을 잡을 것이라고 가정하지 않았습니다.

bool endRequest = false;

try
{
    .. do stuff
    endRequest = true;
}
catch {}

if (endRequest)
    Resonse.End();


답변

그냥 넣어

Response.End();

마침내try 블록이 아닌 블록 내에 있습니다.

이것은 나를 위해 일했습니다 !!!.

다음과 같은 문제가 있습니다 (예외) 코드 구조

...
Response.Clear();
...
...
try{
 if (something){
   Reponse.Write(...);
   Response.End();

   return;

 }

 some_more_code...

 Reponse.Write(...);
 Response.End();

}
catch(Exception){
}
finally{}

예외가 발생합니다. 나는 response.End () 후에 실행할 코드 / 작업이있는 곳에서 예외가 발생한다고 생각합니다. . 제 경우에는 추가 코드가 반환 자체였습니다.

방금 응답을 옮겼을 때 .End (); finally 블록으로 (그리고 그 자리에 리턴을 남겨 두었습니다. 이로 인해 try 블록의 나머지 코드를 건너 뛰고 점프합니다. finally 블록으로 합니다 (포함 함수를 종료하지 않음)) Exception 발생이 중단되었습니다.

다음은 정상적으로 작동합니다.

...
Response.Clear();
...
...
try{
 if (something){
   Reponse.Write(...);

   return;

 }

 some_more_code...

 Reponse.Write(...);

}
catch(Exception){
}
finally{
    Response.End();
}


답변

Response.End () 메서드 의 예외에는 특수 catch 블록을 사용하십시오.

{
    ...
    context.Response.End(); //always throws an exception

}
catch (ThreadAbortException e)
{
    //this is special for the Response.end exception
}
catch (Exception e)
{
     context.Response.ContentType = "text/plain";
     context.Response.Write(e.Message);
}

또는 파일 처리기를 빌드하는 경우 Response.End ()를 제거하십시오.


답변

나를 위해서만 작동

HttpContext.Current.ApplicationInstance.CompleteRequest ().

https://stackoverflow.com/a/21043051/1828356