Как избежать Response.End() Исключение "Тема была прервана" во время загрузки файла Excel

Я попытался преобразовать свой набор данных в Excel и загрузить этот файл Excel. Я получил требуемый файл Excel. Но System.Threading.ThreadAbortException вызывался при каждой загрузке Excel. Как решить эту проблему?.. Пожалуйста, помогите мне...

Я вызываю этот метод на моем экране aspx. Там же то же самое исключение вызвало этим методом.

Я вызываю эту публичную функцию void ExportDataSet(DataSet ds) на многих экранах aspx, а также поддерживаю метод регистрации ошибок для исключений, которые возникают во время выполнения, когда эти исключения записываются в файлы.txt. Так что это же исключение регистрируется во всех текстовых файлах экрана aspx. Я просто хочу избежать этого исключения из метода, объявленного в файле класса метода, в 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
   {                
   }
}

18 ответов

Я исследовал онлайн и увидел, что 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();

Надеюсь, поможет

Переместите Response.End() за пределы блоков Try/Catch и Using.

Предполагается, что для исключения остальной части запроса выдается исключение, вы просто не должны были его перехватывать.

bool endRequest = false;

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

if (endRequest)
    Resonse.End();

Похоже, тот же вопрос, что и:

Когда вызывается ASP.NET System.Web.HttpResponse.End(), текущий поток прерывается?

Так что это по замыслу. Вам нужно добавить улов для этого исключения и изящно "игнорировать" его.

У меня только работает

HttpContext.Current.ApplicationInstance.CompleteRequest ().

/questions/11892557/obrabotka-isklyuchenij-threadabortexception-v-aspnet-pri-vyipolnenii-metoda-responseend/11892576#11892576

Просто положи

Response.End();

в блоке finally, а не в блоке try.

Это сработало для меня!!!

У меня была следующая проблемная (с исключением) структура кода

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

   return;

 } 

 some_more_code...

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

}
catch(Exception){
}
finally{}

и это бросает исключение. Я подозреваю, что Исключение выдается там, где есть код / ​​работа для выполнения после ответа.End();, В моем случае дополнительный код был просто возвращением.

Когда я просто переместил ответ.End(); к блоку finally (и оставив возвращение на своем месте - что вызывает пропуск остального кода в блоке try и переход к блоку finally (а не только к выходу из содержащей функции)), исключение прекратилось.

Следующие работы ОК:

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

   return;

 } 

 some_more_code...

 Reponse.Write(...);

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

Используйте специальный блок catch для исключения метода Response.End()

{
    ...
    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(), если вы строите обработчик файлов

       My JSON file-download was solved by using the blow code:

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

 But Excel file-download was solved by the below way:

 try {
      .....
     }
        catch (System.IO.IOException iex)
        {
            throw (iex);
        }
        catch (System.Threading.ThreadAbortException)
        {
            throw new Exception("ABORTED");//make a custom msg here and catch it 
                                           //where required to continue the rest 
                                           //of the work flow.
        }
        catch (Exception exx)
        {
            throw (exx);
        }
        finally
        {
           ....
        }

Я удалил кнопку ссылки из панели обновления, а также прокомментировал успех Response.End()!!!

Это не проблема, но это дизайн. Основная причина описана на странице поддержки Microsoft.

Метод Response.End завершает выполнение страницы и переносит выполнение в событие Application_EndRequest в конвейере событий приложения. Строка кода, следующая за Response.End, не выполняется.

Предоставленное решение:

Для Response.End вызовите метод HttpContext.Current.ApplicationInstance.CompleteRequest вместо Response.End, чтобы пропустить выполнение кода для события Application_EndRequest

Вот ссылка: https://support.microsoft.com/en-us/help/312629/prb-threadabortexception-occurs-if-you-use-response-end--response-redi

Я знаю, это старый вопрос, но я не нашел здесь решения. После нескольких попыток я обнаружил, что причиной было добавление "<asp:UpdatePanel".

После (повторного) перемещения все работает нормально, как и раньше.

Мне помогло зарегистрировать кнопку, которая вызывает код за кодом в качестве элемента управления обратной передачей.

protected void Page_Init(object sender, EventArgs e)
{
    ScriptManager.GetCurrent(this.Page).RegisterPostBackControl(btnMyExport);
}

Ошибка для Response.END(); потому что вы используете панель обновления asp или любой элемент управления, который использует javascript, попробуйте использовать нативный элемент управления из asp или html без javascript или scriptmanager или сценариев и повторите попытку

Сбросьте ответ клиенту перед response.end()

Подробнее о методе Response.Flush

Так что используйте нижеприведенный код, прежде чем response.End();

response.Flush();  

Я нашел причину. Если вы удалите панели обновления, он прекрасно работает!

Я рекомендую это решение:

  1. Не использовать response.End();

  2. Объявите этот глобальный var: bool isFileDownLoad;

  3. Сразу после вашего (response.Write(sw.ToString());) set ==> isFileDownLoad = true;

  4. Замените ваш рендер как:

    /// AEG : Very important to handle the thread aborted exception
    
    override protected void Render(HtmlTextWriter w)
    {
         if (!isFileDownLoad) base.Render(w);
    } 
    

Я обнаружил, что следующее работает лучше...

   private void EndResponse()
    {
        try
        {
            Context.Response.End();
        }
        catch (System.Threading.ThreadAbortException err)
        {
            System.Threading.Thread.ResetAbort();
        }
        catch (Exception err)
        {
        }
    }

Я использовал все вышеперечисленные изменения, но все же у меня возникала та же проблема с моим веб-приложением.

Затем я связался со своим хостингом и попросил их проверить, не блокирует ли какое-либо программное обеспечение или антивирус наши файлы для передачи по HTTP. или Интернет-провайдер / сеть не позволяет передавать файл.

Они проверили настройки сервера и пропустили "Общий брандмауэр центра данных" для моего сервера, и теперь наше приложение может загрузить файл.

Надеюсь, что этот ответ кому-то поможет. Вот что сработало для меня

Другие вопросы по тегам