Исключение 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();
}
}
}