2009-06-18 2 views
18

В приведенном ниже коде иногда SomeFunctionCall() генерирует исключение «Thread was an aborted». Почему код кода B никогда не запускается? Создает ли ASP.NET новый поток для каждого вызова метода? Я был удивлен, увидев, что, когда это исключение происходит, код в блоке b никогда не запускается, метод возвращается, и мое приложение продолжает работать. Может ли кто-нибудь объяснить это?Исключение ASP.NET «Тема прерывается» вызывает метод выхода

Спасибо.

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


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

    // CODE BLOCK B 
    // ... 

} 

ответ

29

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

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

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

+1

Итак, как я могу заставить его игнорировать это исключение и продолжить выполнение кода в блоке B? –

+0

Вы уверены, что хотите? Если someFunctionCall перенаправляет или заканчивает отклик, вы, вероятно, не должны его продолжать – SLaks

+0

Что делает someFunctionCall? – SLaks

-2

Попробуйте так:

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

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

Это неправильно. Вы не должны сравнивать «сообщение» исключений с жестко запрограммированной строкой. Вместо этого вы можете написать 'catch (ThreadAbortException) {} catch (Exception ex) {...}'.Кроме того, нет смысла вызывать 'Response.End', если уже существует« ThreadAbortException ». – SLaks

+0

Он работает нормально, даже если он выглядит неправильно. – Tarik

+0

P.s: Решения выше не работали для меня, как у большинства людей. Независимо от того, что я сделал, это не работало, так что это единственное решение, которое я нашел и прекрасно работает. – Tarik

1

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

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

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

При использовании этого метода обхода, код, который следует Response.Redirect выполняется. Для Server.Transfer используйте вместо этого метод Server.Execute.

Смежные вопросы