2011-11-23 31 views
6

Tôi có đoạn mã sau từ cuốn sách "Lập trình đồng thời trên Windows":Tại sao CLR lại ném ThreadAbortException?

void Main() 
{ 
    try 
    { 
     try 
     { 
      Console.WriteLine("Inside Main Method"); 
      Thread.CurrentThread.Abort(); 
     } 
     catch(ThreadAbortException) 
     { 
      Console.WriteLine("Inside First Catch"); 
      // Trying to swallow but CLR throws it again.... 
     } 
    } 
    catch(ThreadAbortException) 
    { 
     Console.WriteLine("Inside Second Catch"); 
     //Thread.ResetAbort(); 
    } 
} 

Tôi muốn biết tại sao như CLR tái ném ThreadAbortException? Và nó tiếp tục làm cho đến khi tôi gọi "Thread.ResetAbort()". Thứ hai, có bất kỳ ngoại lệ nào được xác định bởi hệ thống khác, được xử lý đặc biệt từ CLR không?

+0

Cũng lưu ý rằng mã, gọi Thread.ResetAbort() cần có sự cho phép đặc biệt để có thể làm như vậy. Vì vậy, nếu bạn đang lưu trữ CLR hoặc tạo một AppDomain bạn có thể sử dụng tính năng này để làm cho các chủ đề hủy bỏ xác định hơn. – Konstantin

Trả lời

15

Tôi muốn biết tại sao như CLR tái ném ThreadAbortException?

Vì chuỗi đang bị hủy. Mọi người xử lý tất cả các trường hợp ngoại lệ tất cả các thời gian, mặc dù làm như vậy là nguy hiểm. Nó sẽ là kỳ lạ nếu một thói quen ghi nhật ký lỗi, nói, giữ một sợi được cho là sẽ bị hủy diệt mãi mãi, phải không?

có ngoại lệ nào được hệ thống xác định khác, được xử lý đặc biệt từ CLR không?

Có, có một số. Ví dụ, trong số các ngoại lệ ngăn xếp và bộ nhớ ngoài, cũng có các hành vi đặc biệt.

+1

Cảm ơn câu trả lời. Chỉ muốn hỏi, bây giờ cho rằng tôi nhận thức được hành vi này, là nó khuyến khích thực hành để đóng gói chuỗi dựa trên thread bên trong "ThreadAbortException" try-catch khối? Khi ngoại lệ là anyways sẽ được tái ném, hành vi có thể gây ngạc nhiên cho một người không nhận thức được cách hành vi ngoại lệ này hoạt động. –

+4

@PawanMishra: Hai quy tắc tốt cần lưu ý. Đầu tiên là "không bao giờ hủy bỏ một chủ đề". Chấm dứt một sợi bình thường; nếu bạn không thể, hãy giết toàn bộ quá trình. Hủy bỏ một sợi là * cực kỳ nguy hiểm *. Thứ hai, "không bao giờ xử lý một ngoại lệ mà bạn không thể làm điều gì đó về." Không bao giờ có gì tốt để làm khi một sợi bị hủy bỏ. Vì bạn sẽ không bao giờ hủy bỏ một chuỗi, và sẽ không bao giờ xử lý ngoại lệ nếu bạn làm thế, việc viết khối catch là một chút vô nghĩa, đúng không? –

+0

Hỏi lại câu hỏi thứ hai của OP: _Are_ có bất kỳ "ngoại lệ được xác định hệ thống nào [có] được điều trị đặc biệt từ CLR" không? Có trạng thái luồng/quá trình làm cho mọi thứ xảy ra, nhưng tôi không thấy các ngoại lệ một mình là đặc biệt, như có thể thấy [ở đây] (http://share.linqpad.net/hs2pkf.linq). Rõ ràng tôi đã phải nhảy một hoặc hai vòng để cho phép mã của tôi (lại) ném một 'ThreadAbortException' bản thân mình, và có thể có những ngoại lệ khác mà làm những điều buồn cười khi ném, nhưng những điều này dường như không. (True stack overflow và aborted thread _states_ rõ ràng là có điều trị đặc biệt.) –

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