Исключение ASP.NET "Прерывание потока" вызывает метод для выхода

В приведенном ниже коде иногда someFunctionCall() генерирует исключение:

Тема была прервана.

Почему код в блоке кода Б никогда не запускается? ASP.NET запускает новый поток для каждого вызова метода? Я был удивлен, увидев, что когда происходит это исключение, код в блоке B никогда не запускается, метод возвращается, и мое приложение продолжает работать. Может кто-нибудь объяснить это?

public void method()
{
     // CODE BLOCK A
     //...    

     try 
     {
         someFunctionCall(); // this call is generating thread abort exception
     }
     catch(Exception ex)
     {
         // log exception message
     }

    // CODE BLOCK B
    // ...    
}

Ответ 1

Это ThreadAbortException; это особое исключение, которое автоматически возвращается в конце каждого блока catch, если вы не вызываете Thread.ResetAbort().

ASP.Net-методы, такие как Response.End или Response.Redirect (если вы не проходите false), выкидите это исключение для завершения обработки текущей страницы; ваш someFunctionCall(), вероятно, вызывает один из этих методов.

ASP.Net сама обрабатывает это исключение и вызывает ResetAbort для продолжения обработки.

Ответ 2

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

Для Response.Redirect используйте перегрузку Response.Redirect(String url, bool endResponse), которая передает значение false для параметра endResponse для подавления внутреннего вызова Response.End. Например:

Response.Redirect ("nextpage.aspx", false);

Если вы используете этот обходной путь, выполняется код, следующий за Response.Redirect. Вместо Server.Transfer используйте метод Server.Execute.

Ответ 3

Попробуйте следующим образом:

Это мой метод расширения:

 public static void WriteJSONObject(this HttpResponse response, object content) {
            response.ContentType = "application/json";
            response.Write(new JavaScriptSerializer().Serialize(content));
            response.End();

 }

И логика:

public void RegisterUser() {
    try {
        Response.WriteJSONObject(new { Result = "See hello" });
    } 
    catch (Exception err) {
        if (err.Message != "Thread was being aborted.")
            Response.WriteJSONObject(new { Result = err.Message });
        else {
            Response.End();
        }
    }
}