2010-03-04 12 views
23

Próbuję zamknąć odpowiedź, używając Context.Response.End, ale pojawia się błąd "Thread was being aborted".Context.Response.End() i wątek został przerwany

Jak poprawnie zamknąć odpowiedź bez wyzwalania wyjątku?

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) { 

} 

rozwiązany przez siebie kod powinien wyglądać

try { 
    Context.Response.End(); 
} catch (ThreadAbortException err) { 

} 
catch (Exception err) { 
} 
+0

nie masz respose.end wewnątrz bloku try catch? – Andrew

+0

Dodałem mój kod. Tak, dodałem Context.Response.End(); wewnątrz bloku Try/catch i jak widać główny blok Try/catch, który jest również błędem przechwytywania "Wątek został przerwany". – Tomas

+1

rozwiązywane przez siebie kod powinien wyglądać spróbować { } catch (ThreadAbortException Err) { } catch (Exception Err) { } – Tomas

Odpowiedz

26

Czy istnieje konkretny powód nie używasz context.ApplicationInstance.CompleteRequest() zamiast?

Metoda ta zwarcie rurociąg ASP.NET (z wyjątkiem przypadku EndRequest) bez rzucania ThreadAbortException więc nie będzie potrzebował dodatkowego try/catch blok, i będzie również doświadczenie lepszą wydajność.

+1

[MSDN artykułu tłumacząc to] (http: // support .microsoft.com/kb/312629/en-us) – snumpy

+1

Właśnie próbowałem tego (trochę spóźniony na imprezę). Wydawało się, że nie działa poprawnie: na pewno nie wyrzucił wyjątku Response.End(), ale spowodowało to, że zawartość strony .aspx została dołączona do tego, co już napisałem do Response.OutputStream . Jedną opcją może być brak zawartości w pliku .aspx, ale użyłem tego, aby wyświetlać zawartość pod kątem błędów. – Kate

2

Błąd: wątek został przerwany. w System.Threading.Thread.AbortInternal() w System.Threading.Thread.Abort (Object stateInfo) w System.Web.HttpResponse.End()

Ten błąd występuje głównie w przypadku użycia Response.End, Response.Redirect lub Server.Transfer

Przyczyna: Metoda Response.End kończy wykonywanie strony i przesuwa wykonanie do zdarzenia Application_EndRequest w potoku zdarzenia aplikacji. Linia kodu występująca po Response.End nie jest wykonywana.

Ten problem występuje w metodach Response.Redirect i Server.Transfer, ponieważ obie metody wywołują metodę Response.End wewnętrznie.

Rozdzielczość/Rozwiązanie:

Można użyć instrukcji try-catch do połowu tego wyjątku

lub

Dla Response.End, należy wywołać metodę HttpContext.Current.ApplicationInstance.CompleteRequest zamiast Response.End, aby ominąć wykonanie kodu do zdarzenia Application_EndRequest. W przypadku Response.Redirect użyj przeciążenia, Response.Redirect (String url, bool endResponse), który przekazuje wartość false dla parametru endResponse w celu zignorowania wewnętrznego wywołania Response.End. Na przykład: ex: Response.Redirect ("nextpage.aspx", false); Jeśli skorzystasz z tego obejścia, wykonywany jest kod następujący po Response.Redirect. W przypadku Server. Transfer należy zamiast tego użyć metody Server.Execute.

7

Wypróbuj response.OutputStream.Close(); zamiast response.End(); To pomoże!

+0

Pracowałem dla mnie! Dzięki! – Flea

0

polecam tego rozwiązania:

  1. Nie używaj Response.End();

  2. Deklaracja tego globalnego var: bool isFileDownLoad;

  3. Tuż po twoim (response.Write (sw.ToString());) set ==> isFileDownLoad = true;

  4. nadpisało Render jak:

    /// /// AEG: Bardzo ważne jest, aby obsłużyć wyjątek wątek przerwany /// /// override protected void Render (HtmlTextWriter w) { jeśli (! IsFileDownLoad) base.Render (w); }

0

Albo można umieścić context.Response.End() wewnątrz bloku finally. W ten sposób nie będziesz musiał przejmować się niepożądanym wyjątkiem ThreadAbortException, ani ignorować prawdziwego wyjątku ThreadAbortException (który jest zły). Nie będziesz także ignorował etapów potoku.

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

To pomogło mi obsłużyć Thread was being aborted wyjątek,

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); 
    } 
    } 

jeśli użyć następujących poniższym kodzie zamiast HttpContext.Current.Response.End(), dostaniesz Server cannot append header after HTTP headers have been sent wyjątek.

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

Innym Fix co uważam jest 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(); 
     } 
    } 

Nadzieja pomaga

Powiązane problemy