2010-01-06 65 views

Trả lời

86

Application.ThreadException là cụ thể cho Windows Forms. Winforms chạy trình xử lý sự kiện để đáp ứng với các tin nhắn được gửi tới Windows. Ví dụ, sự kiện Click, tôi chắc rằng bạn biết chúng. Nếu xử lý sự kiện như vậy ném một ngoại lệ thì có một back-stop bên trong vòng lặp tin nhắn Winforms mà bắt ngoại lệ đó.

Rào cản đó kích hoạt sự kiện Application.ThreadException. Nếu bạn không ghi đè, người dùng sẽ nhận được ThreadExceptionDialog. Điều này cho phép anh ta bỏ qua ngoại lệ và tiếp tục chạy chương trình của bạn. Không phải là một ý tưởng tuyệt vời btw.

Bạn có thể tắt hành vi này bằng cách gọi Application.SetUnhandledExceptionMode() trong phương thức Main() trong Program.cs. Nếu không có backstop tại chỗ, điều bình thường xảy ra khi một thread chết từ một ngoại lệ unhandled: AppDomain.UnhandledException cháy và chương trình chấm dứt.

Fwiw: "ThreadException" là một lựa chọn tên rất kém. Nó không liên quan gì đến chủ đề.

+0

Và làm thế nào để dừng ứng dụng WinForms khỏi sự cố khi xảy ra 'Application.ThreadException'. Tôi đưa ra một câu hỏi cho [[ở đây] (http://stackoverflow.com/questions/23153287/suppressing-application-threadexception-and-appdomain-currentdomain-unhandledexc)] với mã C# nhỏ của tôi. – Mahesha999

+2

Tôi luôn luôn đọc nó như là ngoại lệ ứng dụng-thread, cho rằng winforms được ràng buộc vào một chủ đề duy nhất. – Gusdor

0

Điều tốt là, ThreadException xảy ra do sự cố với chuỗi của bạn, Unhandled Exception bị kích hoạt nếu bạn mã ném một ngoại lệ không được xử lý.

Cách dễ dàng để tạo ra ứng dụng thứ hai là tạo ứng dụng mà không cần thử ... chặn các khối và ném ngoại lệ.

Bây giờ nếu bạn cần bảo hiểm, bạn có thể xử lý cả hai, tuy nhiên nếu bạn nắm bắt và xử lý exceptions chính xác thì bạn không cần trình xử lý UnhandledException vì nó giống như nắm bắt tất cả.

+0

cảm ơn - những gì tôi không quá rõ ràng là nếu xử lý UnhandledException tôi cũng sẽ bắt ThreadException - dường như không phải là trường hợp – JohnIdol

18

OK - tôi đã có nó trước mặt tôi, chút mã này từ msdn là khá tự giải thích:

public static void Main(string[] args) 
{ 
    // Add the event handler for handling UI thread exceptions to the event. 
    Application.ThreadException += new 
     ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException); 

    // Set the unhandled exception mode to force all Windows Forms 
    // errors to go through our handler. 
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 

    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException += 
     new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 

    // Runs the application. 
    Application.Run(new ErrorHandlerForm()); 
} 
+3

điều này trái ngược với câu trả lời khác của serhio khi ông nói: UnhandledExceptionMode.ThrowException nên được đặt trước khi xử lý sự kiện ThreadException được nối. Không chắc chắn nếu thứ tự thực sự quan trọng ... –

+0

@DavidePiras có, và có điều gì đó u ám hơn. SetUnhandledException dường như không tạo ra sự khác biệt nào trong trường hợp của tôi. – nawfal

33

Trong các ứng dụng sử dụng Biểu mẫu Windows, các ngoại lệ chưa được giải quyết trong chuỗi ứng dụng chính gây ra sự kiện Application.ThreadException được nêu ra. Nếu sự kiện này được xử lý, hành vi mặc định là ngoại lệ chưa được xử lý không chấm dứt ứng dụng, mặc dù ứng dụng được để ở trạng thái không xác định. Trong trường hợp đó, sự kiện UnhandledException không được nâng lên. Có thể thay đổi hành vi này bằng cách sử dụng tệp cấu hình ứng dụng hoặc bằng cách sử dụng phương thức Application.SetUnhandledExceptionMode để thay đổi chế độ thành UnhandledExceptionMode.ThrowException trước khi xử lý sự kiện ThreadException. Điều này chỉ áp dụng cho chuỗi ứng dụng chính. Sự kiện UnhandledException được nâng lên cho các ngoại lệ chưa được giải quyết được ném trong các chủ đề khác.

Bắt đầu với Visual Studio 2005, các trực quan khung ứng dụng cơ bản cung cấp sự kiện khác cho trường hợp ngoại lệ unhandled trong thread ứng dụng chính - WindowsFormsApplicationBase.UnhandledException. Sự kiện này có đối tượng đối số sự kiện có cùng tên với đối tượng đối số sự kiện được sử dụng bởi AppDomain.UnhandledException, nhưng với các thuộc tính khác nhau. Cụ thể, đối tượng đối số sự kiện này có thuộc tính ExitApplication cho phép ứng dụng tiếp tục chạy, bỏ qua ngoại lệ chưa được xử lý (và để ứng dụng ở trạng thái không xác định). Trong trường hợp đó, sự kiện AppDomain.UnhandledException không được nâng lên.

Application.ThreadException có thể bị bắt và ứng dụng có thể tiếp tục (nói chung không phải là một ý tưởng tuyệt vời, nhưng đối với ứng dụng như chạy định kỳ một số hành động này là giải pháp tốt).

Để bắt ngoại lệ xảy ra trong các chủ đề không được tạo và sở hữu bởi Windows Biểu mẫu, hãy sử dụng AppDomain.UnhandledException. Nó cho phép ứng dụng ghi lại thông tin về ngoại lệ trước khi trình xử lý mặc định của hệ thống báo cáo ngoại lệ cho người dùng và chấm dứt ứng dụng.
Việc xử lý ngoại lệ này không ngăn ứng dụng bị chấm dứt.
Tối đa có thể được thực hiện (dữ liệu chương trình có thể bị hỏng khi ngoại lệ không được xử lý) đang lưu dữ liệu chương trình để khôi phục sau này. Sau đó miền ứng dụng được tải xuống và ứng dụng chấm dứt.

Bắt đầu với NET 4, sự kiện này không được đưa lên cho trường hợp ngoại lệ mà tham nhũng trạng thái của quá trình, chẳng hạn như ngăn xếp tràn hoặc vi phạm truy cập, trừ trường hợp xử lý sự kiện là an ninh quan trọng và có thuộc tính HandleProcessCorruptedStateExceptionsAttribute.

Để biết thêm chi tiết, hãy xem MSDN.

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