Context.Response.End() и Thread были прерваны
Я пытаюсь закрыть ответ с помощью Context.Response.End
, но получить ошибку "Thread was being aborted"
.
Как правильно закрыть ответ без запуска исключения?
try {
Context.Response.Clear();
Context.Response.ContentType = "text/html";
//Context.Response.ContentType = "application/json";
JsonObjectCollection collection = new JsonObjectCollection();
collection.Add(new JsonNumericValue("resultcode", 1));
collection.Add(new JsonStringValue("sourceurl", exchangeData.cUrl));
collection.Add(new JsonStringValue("filename", fileName));
collection.Add(new JsonStringValue("filesize", fileSize));
collection.Add(new JsonStringValue("fileurl", Common.GetPDFURL + outputFileName));
JsonUtility.GenerateIndentedJsonText = true;
Context.Response.Write(collection);
try {
Context.Response.End();
} catch (ThreadAbortException exc) {
// This should be first catch block i.e. before generic Exception
// This Catch block is to absorb exception thrown by Response.End
}
} catch (Exception err) {
}
Решенный сам, код должен выглядеть как
try {
Context.Response.End();
} catch (ThreadAbortException err) {
}
catch (Exception err) {
}
Ответы
Ответ 1
Есть ли конкретная причина, по которой вы не используете context.ApplicationInstance.CompleteRequest()
?
Этот метод сократит конвейер ASP.NET(за исключением события EndRequest), не бросая ThreadAbortException
, поэтому вам не понадобится дополнительный блок try
/catch
, и вы также получите более высокую производительность.
Ответ 2
Попробуйте response.OutputStream.Close(); вместо response.End();
Это поможет!
Ответ 3
Ошибка: поток прерывался. в System.Threading.Thread.AbortInternal() в System.Threading.Thread.Abort(Object stateInfo) в System.Web.HttpResponse.End()
Эта ошибка возникает в основном, если вы используете Response.End, Response.Redirect или Server.Transfer
Причина. Метод Response.End завершает выполнение страницы и переносит выполнение в событие Application_EndRequest в конвейере событий приложений. Строка кода, которая следует за Response.End, не выполняется.
Эта проблема возникает в методах Response.Redirect и Server.Transfer, потому что оба метода вызывают Response.End внутри.
Разрешение/Решение:
Вы можете использовать оператор try-catch для исключения этого исключения
или
Для Response.End вызовите метод HttpContext.Current.ApplicationInstance.CompleteRequest вместо Response.End, чтобы обойти выполнение кода в событие Application_EndRequest. Для Response.Redirect используйте перегрузку Response.Redirect(String url, bool endResponse), которая передает значение false для параметра endResponse для подавления внутреннего вызова Response.End. Например: ex: Response.Redirect( "nextpage.aspx", false); Если вы используете этот обходной путь, выполняется код, следующий за Response.Redirect. Для Server.Transfer вместо этого используйте метод Server.Execute.
Ответ 4
Я рекомендую это решение:
-
Не используйте response.End();
-
Объявить этот глобальный var: bool isFileDownLoad;
-
Сразу после вашего (response.Write(sw.ToString());) set == > isFileDownLoad = true;
-
Отмените свой Render как:
///
///AEG: очень важно обрабатывать исключение прерывания потока
///
///
override protected void Render (HtmlTextWriter w)
{ if (! isFileDownLoad) base.Render(w);
}
Ответ 5
Или вы можете разместить context.Response.End() внутри блока finally. Таким образом вам не придется заботиться о нежелательном ThreadAbortException или игнорировать реальное исключение ThreadAbortException (что плохо). Вы также не будете игнорировать этапы конвейера.
try
{
context.Response.ContentType = "application/json";
context.Response.ContentEncoding = Encoding.UTF8;
if (NotAuthorized())
{
context.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
return;
}
context.Response.Write(MakeJsonStuff());
}
catch (Exception ex)
{
LogException(ex);
context.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
context.Response.Write(MakeJsonError(ex));
}
finally
{
context.Response.End();
}
Ответ 6
Это помогло мне обработать исключение 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();
Еще одно исправление, которое я нашел: Thread.BeginCriticalRegion();
try
{
//Write HTTP output
HttpContext.Current.Response.Write(Data);
} catch (Exception exc) {}
finally {
try {
//Notifies a host that execution is about to enter a region of code in which the effects of a thread abort or unhandled exception might jeopardize other tasks in the application domain.
Thread.BeginCriticalRegion();
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();
Thread.EndCriticalRegion();
}
}
Надеюсь, что это поможет