2011-01-23 32 views
5

Tôi có chủ đề Như thế này, sau khi tôi xem ví dụ link textném một ngoại lệ trong chủ đề C#

ThreadStart _threadStart = new ThreadStart(delegate() 
{ 
     try 
     { 
      threadFunction(httpContext); 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
}); 
Thread _thread = new Thread(_threadStart); 
    _thread.Start(); 

khi một ngoại lệ xảy ra nó doesnt lại ném vào các chủ đề đã bắt đầu nó. Vì vậy, những gì tôi đang làm sai hoặc làm thế nào để làm điều đó?

Lưu ý: cảm ơn tất cả các ý kiến ​​trong tiến

+6

Lưu ý bạn nên * không bao giờ * rethrow một ngoại lệ như bạn làm ở đó. Chỉ cần làm 'ném; 'trong khối catch đủ ... – Joey

+0

tôi biết bu i ném ngoại lệ tùy chỉnh được thừa hưởng từ" System.Exception "với thông báo – Hiyasat

+1

Bạn phải ném một ngoại lệ * mới * với thông tin bạn muốn thêm. Vượt qua * ngoại lệ * ban đầu là InnerException. Làm điều này chỉ khi thông tin được thêm có giá trị cao vì nó giúp khắc phục sự cố khó khăn hơn. –

Trả lời

7

Ngoại lệ sẽ được ném, nhưng điều đó sẽ chỉ kết thúc chuỗi. Ngoại lệ không được ném lại trong chuỗi đã bắt đầu.

+0

Tại sao điều đó? và giải pháp tốt nhất để làm điều đó là gì? – Hiyasat

+1

@Hiyasat: Nếu một chuỗi có thể ném bất kỳ ngoại lệ nào vào chuỗi bắt đầu của nó bất kỳ lúc nào, sẽ rất khó để triển khai chuỗi bắt đầu để xử lý điều đó. Bạn phải truyền đạt ngoại lệ trở lại chủ đề bắt đầu giống như bạn gửi lại bất kỳ kết quả nào khác, ví dụ bằng cách sử dụng một varaible mà cả hai luồng đều có quyền truy cập. – Guffa

1

Trường hợp ngoại lệ được ném ra, ngoại trừ tôi đoán bạn không nhìn thấy nó, vì nó được ném vào thread khác. Do đó, chuỗi giao diện người dùng (hoặc bất kỳ chuỗi nào được gọi ra luồng khác), không thể bắt ngoại lệ, vì nó không nhìn thấy nó.

Nếu bạn ghi ngoại lệ vào tệp chẳng hạn, tôi chắc chắn bạn sẽ thấy nó. :)

+0

Ngoại lệ sẽ được nhìn thấy trên bất kỳ chủ đề nào được nêu ra. Tôi nghĩ rằng không có ngoại lệ ở tất cả - thread chỉ hoàn thành bình thường. –

+0

Tôi chắc chắn có ngoại lệ xảy ra nhưng nó liều không ném vào chủ đề chính – Hiyasat

2

Bạn có chắc chắn rằng ngoại lệ được ném không? Nếu một chuỗi không thành công với một ngoại lệ, toàn bộ ứng dụng sẽ sụp đổ, bạn có thể nhận thấy sự kiện AppDomain.CurrentDomain.UnhandledException (lưu ý rằng khi sự kiện đã được kích hoạt, bạn không thể ngăn ứng dụng của mình kết thúc, nhưng có thể dọn sạch tài nguyên và lưu dữ liệu quan trọng - xem tài liệu sự kiện để biết thêm thông tin).

Tuy nhiên, để trích dẫn accepted answer từ thread bạn gọi:

Bất kỳ chủ đề đó đặt ra một ngoại lệ cấp cao nhất chỉ ra một vấn đề lớn.

Bạn nên thử đăng nhập ngoại lệ và/hoặc báo hiệu (các) chủ đề khác mà chuỗi này không thành công.

0

Tôi nghĩ có lẽ bạn nên xem xét sử dụng lớp BackgroundWorker. Bạn có thể đăng ký sự kiện RunWorkerCompleted và nó có thuộc tính Error sẽ chứa ngoại lệ của bạn.

+0

Cảm ơn, nhưng tôi đã tìm thấy thứ gì đó mạnh mẽ hơn trong .NET 4 Tác vụ http://blogs.msdn.com/b/pfxteam/archive/2009/05/31/9674669.aspx – Hiyasat

+0

Cảm ơn bạn đã liên kết - Công việc trông tuyệt vời, tôi chưa có cơ hội để kiểm tra chúng. – antsyawn

6

Tôi nghĩ rằng trái tim của vấn đề là để hiểu rằng các ngoại lệ xảy ra trong một chuỗi sẽ không được chuyển đến chuỗi gọi để xử lý.

Ví dụ, nói rằng bạn có một phương pháp nổi loạn:

private static void RebelWithoutACause() 
{ 
    throw new NullReferenceException("Can't touch this!"); 
} 

Hãy nói rằng bạn tạo ra một chủ đề mới mà các cuộc gọi phương pháp này trong chương trình của bạn, và trở thành một lập trình viên an toàn, bạn quyết định phong bì công việc trong một try/catch khối:

private static void Main(string[] args) 
{ 
    try 
    { 
     var thread = new Thread(RebelWithoutACause); 
     thread.Start(); 
     thread.Join(); 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex.ToString()); 
    } 
} 

Tuy nhiên, nếu bạn chạy trong trình gỡ lỗi, bạn sẽ tìm ra rằng bạn sẽ không bao giờ đến được với các khối catch, và thay vào đó thread sẽ bị giết chết, và các chương trình gỡ rối sẽ phàn nàn rằng bạn có một ngoại lệ chưa được giải quyết .

Bạn cần chọn cách xử lý các ngoại lệ, nhưng việc xử lý cần phải xảy ra bên trong mỗi phương thức nhập chủ đề. Xử lý điển hình bao gồm ghi nhật ký chi tiết, thông báo cho người dùng thông qua giao diện người dùng và tắt ứng dụng của bạn một cách duyên dáng nhất có thể.

+0

giải thích rất tốt! – koumides

0

có thể làm điều gì đó như thế này:

const int numThreads = 8; 
    Thread[] threads = new Thread[numThreads]; 
    Exception[] threadsExceptions = new Exception[numThreads]; 
    for (int i = 0; i < numThreads; i++) { 
     threadsExceptions[i] = null; 
     int closureVariableValue = i; 
     ThreadStart command =() => 
     { 
      try 
      { 
       throw new ArgumentException("thread_" + closureVariableValue + "'s exception"); 
      }catch(Exception any) 
      { 
       threadsExceptions[closureVariableValue] = any; 
      } 
     }; 
     threads[i] = new Thread(command); 
     threads[i].Start(); 
    } 
    for(int i = 0; i < numThreads; i++) 
    { 
     threads[i].Join(); 
     if (threadsExceptions[i] != null) 
     { 
      throw threadsExceptions[i]; 
     } 
    } 
Các vấn đề liên quan