2010-04-27 41 views
6

Hãy xem xét các ứng dụng đơn giản sau đây: một hình thức cửa sổ được tạo ra bởi một "mới C# cửa sổ ứng dụng" chuỗi trong VS đã được sửa đổi một cách sau:bắt ngoại lệ trong Main() phương pháp

public static void Main() 
{ 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 

    try 
    { 
     Application.Run(new Form1()); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("An unexpected exception was caught."); 
    } 

} 

Form1.cs chứa các sửa đổi sau:

private void Form1_Load(object sender, EventArgs e) 
{ 
    throw new Exception("Error"); 

} 

Nếu tôi nhấn F5 trong IDE, như tôi mong đợi, tôi thấy hộp thông báo cho biết ngoại lệ đã bị bắt và ứng dụng thoát.

Nếu tôi đi tới Debug (hoặc Release)/bin và khởi động tệp thực thi, tôi thấy cửa sổ "Ngoại lệ không khớp" chuẩn, có nghĩa là trình xử lý ngoại lệ của tôi không hoạt động.

Rõ ràng, điều đó có liên quan đến ngoại lệ được ném từ một luồng khác mà Application.Run được gọi từ đó. Nhưng câu hỏi vẫn còn - tại sao các hành vi khác nhau tùy thuộc vào việc ứng dụng đã được chạy từ IDE hay từ dòng lệnh? Thực hành tốt nhất để đảm bảo rằng không có trường hợp ngoại lệ nào không được giải quyết trong đơn đăng ký?

+0

@Corvin: vui lòng kiểm tra câu trả lời được chấp nhận, nếu bạn cảm thấy bạn có giải pháp cho câu hỏi của mình. –

Trả lời

10

Thông thường Application.ThreadException sẽ xử lý ngoại lệ trong sự kiện Tải. Bạn sẽ nhận được ThreadExceptionDialog cung cấp các tùy chọn Quit và Continue.

Nhưng không phải khi trình gỡ lỗi được đính kèm. Mệnh đề catch trong vòng lặp tin nhắn hiển thị hộp thoại bị vô ý vô hiệu hóa trong trường hợp đó. Điều đó là cần thiết vì sẽ rất khó khăn để loại trừ các trường hợp ngoại lệ nếu hộp thoại đó xuất hiện khi bạn gỡ lỗi chương trình. Bộ thu bắt này không còn hoạt động nữa, mệnh đề catch của bạn trong phương thức Main() bây giờ được chụp ở ngoại lệ.

Bạn có thể làm cho nó nhất quán bằng cách sử dụng Application.SetUnhandledExceptionMode() trong phương thức Main(). Bạn không nên, ngoại lệ thực sự khó gỡ lỗi nếu bạn làm điều này. Nếu bạn muốn tùy chỉnh xử lý ngoại lệ cho thread UI thì bạn nên đăng ký xử lý Application.ThreadException riêng bạn:

if (!System.Diagnostics.Debugger.IsAttached) 
    Application.ThreadException += myThreadException; 

Bẫy hợp ngoại lệ unhandled trong đề người lao động đòi hỏi phải có một handler AppDomain.UnhandledException. Chúng không thể phục hồi được.

Cũng hãy cẩn thận với lỗi trong Windows 64 bit, ngoại lệ trong sự kiện Tải được nuốt mà không cần chẩn đoán khi trình gỡ lỗi được đính kèm. Buộc chế độ AnyCPU tránh bẫy đó.

+0

@Hans - bạn đang đề cập đến sự kiện 'Form.Load'? Btw, viết đẹp. –

+0

@Peter: vâng. Cảm ơn! –

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