2009-04-22 39 views
13

Tôi có một ý tưởng tại sao nhưng tôi muốn hỏi liệu có ai đó có nắm bắt tốt về lý do ngoại lệ được nêu ra bên trong một chuỗi không bao giờ bị bắt bởi mã bắt đầu nó. Dưới đây là một số mã rất đơn giản để chứng minh những gì tôi muốn nói:Hãy thử/Catch và luồng

using System; 
using System.Collections.Generic; 
using System.Threading; 

namespace TestCrash 
{ 
    class Program 
    { 
     private static void Crash(object control) 
     { 
      AutoResetEvent are = (AutoResetEvent)(((object[])control)[0]); 
      are.Set(); 
      throw new Exception("Burn baby burn"); 
     } 
     static void Main(string[] args) 
     { 
      try 
      { 
       List<WaitHandle> waitHandles = new List<WaitHandle>(); 
       for (int i = 0; i < 100; i++) 
       { 
        AutoResetEvent are = new AutoResetEvent(false); 
        waitHandles.Add(are); 
        object[] procControl = new object[] { are }; 
        ThreadPool.QueueUserWorkItem(Crash, procControl); 
        WaitHandle.WaitAll(waitHandles.ToArray()); 
       } 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.Message); 
      } 
     } 
    } 
} 

Tôi ngây thơ nghĩ rằng bằng cách try/catch tôi sẽ được an toàn, nhưng tôi phát hiện ra cách cứng mà nó không phải là trường hợp (nó là đâm một trong những dịch vụ của tôi).

+0

Lạ thật, tôi sắp bắt đầu một chủ đề tương tự. –

+0

Im chắc chắn ive có bong bóng Ngoại lệ lên đến chuỗi đang gọi. Altho im không sử dụng ThreadPool. chỉ Chủ đề T = chủ đề mới (ThreadStart mới (delegate() {Console.WriteLine ("Crash!"); DoCrashyThingy();})); T.Start(); – Fusspawn

+0

Tôi có thể dễ dàng bị sai lầm về điều đó, hầu hết công việc của tôi là kẻ thù độc ác ghê gớm này .. – Fusspawn

Trả lời

28

Nói chung, bạn không biết nguồn gốc sẽ xuất hiện ở đâu khi ngoại lệ được ném vào chuỗi mới - tại sao nó lại chờ đợi cho chuỗi để ném ngoại lệ?

Hãy suy nghĩ về các ngăn xếp liên quan - khi một ngoại lệ được ném, nó sẽ tăng lên cho đến khi nó đạt đến khối catch thích hợp. Các chủ đề mới có một ngăn xếp hoàn toàn riêng biệt để tạo thread, do đó, nó sẽ không bao giờ đạt được khối catch trong ngăn xếp của việc tạo thread.

EDIT: Tất nhiên, bạn có thể thiết kế hệ thống của mình để tạo chuỗi làm chờ đợi những điều khác xảy ra - giống như vòng lặp thư trong ứng dụng Windows Forms. Các chủ đề mới sau đó có thể bắt ngoại lệ và gửi một tin nhắn đến các chủ đề tạo ra, mà sau đó có thể đối phó với ngoại lệ. Đó không phải là thiết lập bình thường mặc dù - bạn phải làm tất cả một cách rõ ràng.

+0

Cảm ơn, Jon. Điều làm tôi bối rối là nó thực sự làm hỏng quá trình cha mẹ; Tôi sẽ tưởng tượng rằng các chủ đề ít nhất phải chết một cách hòa bình thay vì đưa tất cả mọi thứ xuống với nó. –

+0

Không - vấn đề là một ngoại lệ không mong muốn cũng có thể cho thấy điều gì đó nghiêm trọng sai, và thất bại nhanh chóng nói chung là một ý tưởng tốt hơn. Đây là hành vi mới của .NET 2.0. Xem http://msdn.microsoft.com/en-us/library/ms228965.aspx –

+0

Vì vậy, tôi sẽ kết luận rằng bất kỳ khối mã nào được xếp vào hàng đợi chuỗi phải được bao bọc hoàn toàn trong khối try/catch, là phương pháp hay nhất?Tôi có một dịch vụ mà tôi sẽ không muốn đi xuống chỉ vì một trong những chủ đề của nó gặp rắc rối ... –

2

Đó là một ý tưởng tồi để đưa ra các giả định, đặc biệt là khi có nhiều chủ đề liên quan (bạn biết câu nói cũ).

Tại sao sẽ mã bắt đầu chuỗi thấy ngoại lệ? Mã bắt đầu chuỗi có thể không tồn tại khi ngoại lệ được ném.

+1

như một sang một bên, tôi ghét nói rằng bởi vì nó bỏ qua thực tế rằng chúng tôi yêu cầu các giả định để tồn tại. Câu nói nên đề cập đến sự hiểu biết những giả định của bạn là gì và xác định chúng ở đâu không chính xác. –

2

Chuỗi đang chạy sẽ không bị phát hiện trong câu lệnh try/catch của bạn vì nó đang chạy trong một chuỗi khác. Try/Catch chỉ hoạt động cho chuỗi hiện tại. Những gì bạn cần làm là thử/nắm bắt chức năng đang được chạy bởi luồng và có một số cách để quản lý những gì xảy ra khi sự cố đó xảy ra.

2

Bạn có thể muốn sử dụng một EventGeneratingThread wrapper - điều này sẽ cho phép bạn nắm bắt và xử lý ngoại lệ được ném trong chuỗi từ quá trình tạo ra chúng.

2

Hãy thử thêm điều này trước khi DoWork bạn Sub

<System.Diagnostics.DebuggerNonUserCodeAttribute()> _ 

Tôi đang sử dụng người lao động nền, và tất cả các Catch Cố gắng trong công việc lặp của tôi như bạn mong muốn họ với điều này.