2010-03-04 37 views
23

Tôi đang cố gắng đóng phản hồi bằng cách sử dụng Context.Response.End nhưng nhận lỗi "Thread was being aborted".Context.Response.End() và Chủ đề đã bị hủy bỏ

Làm cách nào để đóng đúng phản hồi mà không kích hoạt ngoại lệ?

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

} 

giải quyết bằng bản thân mình, các mã sẽ giống như

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

} 
catch (Exception err) { 
} 
+0

Bạn có respose.end bên trong một khối try catch? – Andrew

+0

Tôi đã thêm mã của mình. Có, tôi đã thêm Context.Response.End(); bên trong khối try/catch và khi bạn thấy có khối try/catch chính cũng là lỗi bắt "Thread is aborted". – Tomas

+1

giải quyết bằng bản thân mình, các mã sẽ giống như thử {} catch (err ThreadAbortException) {} catch (Exception err) { } – Tomas

Trả lời

26

Có một lý do cụ thể mà bạn không sử dụng context.ApplicationInstance.CompleteRequest() để thay thế?

Phương pháp này sẽ ngắn mạch đường dẫn ASP.NET (ngoại trừ sự kiện EndRequest) mà không cần ném ThreadAbortException để bạn không cần thêm khối try/catch và bạn cũng sẽ có hiệu suất tốt hơn.

+1

[MSDN bài báo giải thích này] (http: // hỗ trợ .microsoft.com/kb/312629/en-us) – snumpy

+1

Tôi vừa thử điều này (một chút muộn cho bữa tiệc). Nó dường như không hoạt động đúng: chắc chắn nó đã không ném các ngoại lệ Response.End() ném, nhưng nó đã dẫn đến nội dung của trang .aspx được gắn vào những gì tôi đã viết cho Response.OutputStream . Một tùy chọn có thể là không có nội dung trong tệp .aspx nhưng tôi đã sử dụng nó để có nội dung hiển thị lỗi. – Kate

2

Lỗi: Chủ đề đã bị hủy. tại System.Threading.Thread.AbortInternal() tại System.Threading.Thread.Abort (Object stateInfo) tại System.Web.HttpResponse.End()

Lỗi này xảy ra chủ yếu nếu bạn sử dụng Response.End, Response.Redirect hoặc Server.Transfer

Nguyên nhân: Phương thức Response.End kết thúc thực thi trang và thay đổi thực thi thành sự kiện Application_EndRequest trong đường ống sự kiện của ứng dụng. Dòng mã tuân theo Response.End không được thực thi.

Sự cố này xảy ra trong các phương thức Response.Redirect và Server.Transfer vì cả hai phương thức đều gọi Response.End trong nội bộ.

Nghị quyết/Giải pháp:

Bạn có thể sử dụng một câu lệnh try-catch để bắt ngoại lệ này

hoặc

Đối với Response.End, gọi phương thức HttpContext.Current.ApplicationInstance.CompleteRequest thay vì Response.End để bỏ qua việc thực thi mã cho sự kiện Application_EndRequest. Đối với Response.Redirect, sử dụng một quá tải, Response.Redirect (String url, bool endResponse) mà đi sai cho tham số endResponse để ngăn chặn các cuộc gọi nội bộ để Response.End. Ví dụ: ví dụ: Response.Redirect (“nextpage.aspx”, false); Nếu bạn sử dụng cách giải quyết này, mã theo sau Response.Redirect được thực thi. Đối với Server.Transfer, sử dụng phương thức Server.Execute để thay thế.

7

Hãy thử phản hồi.OutputStream.Close(); thay vì phản hồi.End(); Nó sẽ giúp bạn!

+0

Làm việc cho tôi! Cảm ơn! – Flea

0

Tôi khuyên bạn nên giải pháp này:

  1. Không sử dụng Response.End();

  2. Khai báo var toàn cục này: bool isFileDownLoad;

  3. Ngay sau khi bạn (phản hồi.Write (sw.ToString());) set ==> isFileDownLoad = true;

  4. Override Render của bạn như:

    /// /// AEG: Rất quan trọng để xử lý các chủ đề hủy bỏ ngoại lệ /// /// override protected void Render (w HtmlTextWriter) { if (! IsFileDownLoad) base.Render (w); }

0

Hoặc bạn có thể đặt context.Response.End() bên trong một cuối cùng khối. Bằng cách đó bạn sẽ không phải quan tâm đến ThreadAbortException không mong muốn, cũng không bỏ qua bất kỳ ThreadAbortException thực sự nào (điều đó là xấu). Bạn cũng sẽ không bỏ qua các giai đoạn của đường ống.

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

này đã giúp tôi để xử lý Thread was being aborted ngoại lệ,

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

nếu bạn sử dụng sau đoạn mã sau thay vì HttpContext.Current.Response.End(), bạn sẽ nhận được Server cannot append header after HTTP headers have been sent ngoại lệ.

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

Một Fix mà tôi tìm thấy là 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(); 
     } 
    } 

Hy vọng nó giúp

Các vấn đề liên quan