2009-07-30 91 views
13

Tôi có một ứng dụng winforms.Winforms bắt đầu với Program.cs, nơi chúng tôi có chính() defined.I đã đặt mã này trong khối try-catch.Tại sao ngoại lệ win32 không bị bắt bởi cơ chế xử lý ngoại lệ C#

[STAThread] 
    static void Main() 
    { 
     try 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new frmSplash()); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
      if (ex.InnerException != null) 
      { 
       MessageBox.Show(ex.InnerException.ToString()); 
      } 
     } 
    } 

Bất cứ khi nào có ngoại lệ win32, cơ chế này không thành công và thông báo ngoại lệ không được giải quyết sẽ được ném và lỗi ứng dụng.
Tôi có 2 câu hỏi liên quan đến mã này:

1) Tại sao không tìm thấy ngoại lệ win32.

2) Thực hành tốt có bắt ngoại lệ ở mức cao nhất hay không.

+0

Ồ, tôi chưa bao giờ thực sự nghĩ về câu hỏi hay, câu trả lời hay này :) – leppie

+0

Hãy bình luận về câu hỏi thứ hai. – Rohit

+0

Có thể bạn có thể đặt câu hỏi SO thứ hai ;-) – Mac

Trả lời

12

CHỈNH SỬA: như Pratik chỉ ra, câu trả lời sau chỉ áp dụng cho .NET 1.0 và .NET 1.1. Bắt đầu với .NET 2.0, ngoại lệ không phải CLS phải được xem là RuntimeWrappedException.


Vì ngoại lệ Win32 không xuất phát từ lớp .NET Exception. Hãy thử:

try { 
} catch (Exception ex) { 
    // .NET exception 
} catch { 
    // native exception 
} 

Xem Catch non-CLSCompliant exceptions in general handlers để biết thêm thông tin.

+4

Điều này không bắt buộc trong .Net 2.0 theo mặc định. Tất cả ngoại lệ không CLS đều được thêm vào như một RuntimeWrappedException. Xem http://msdn.microsoft.com/en-us/library/ms404228.aspx – softveda

+0

Win32Exception

+0

@Pratik: cảm ơn vì liên kết. @Tommy Carlier: cf. Liên kết của Pratik ... – Mac

0

Bạn có thể cần phải bắt như Win32Exception (hoặc ExternalException) thay vì

http://msdn.microsoft.com/en-us/library/system.componentmodel.win32exception.aspx

tôi dường như nhớ rằng Win32Exception thừa hưởng từ ExternalException nhưng ExternalException không kế thừa từ ngoại lệ như vậy sẽ không được đánh bắt bởi mã của bạn .

Chỉnh sửa: Xem câu trả lời khác cho lý do tại sao điều này sai!

Chỉnh sửa 2: Đối với phần thứ hai, như đã nêu trong AnthonyWJones Đó là cách tốt để cho người dùng biết rằng sự cố đã khiến ứng dụng đóng, tuy nhiên tôi khuyên bạn nên sử dụng tuyên bố tiếng Anh đơn giản cho người dùng và ghi lại ngăn xếp ngoại lệ vào tệp nhật ký để bạn sử dụng.

+1

Cả hai điều này đều có nguồn gốc từ ngoại lệ, do đó trên bề mặt của câu hỏi bắt buộc phải hoạt động. Vì sao nó không thấy câu trả lời của tôi. – AnthonyWJones

3

Việc thi hành Application.Run không phải là lỗi. Điều đó đang xảy ra trên một luồng khác (hoặc ít nhất là không đồng bộ).

Ý tưởng hay của nó để thông báo cho người dùng một cách thân thiện rằng ứng dụng đã thất bại trước khi nó biến mất hoàn toàn, tuy nhiên không phải là ý tưởng hay để chỉ bắt được rồi tiếp tục.

3

Mặc dù tôi không biết tại sao khối catch của bạn không hoạt động, hãy thử sử dụng Application ThreadException Event. Điều này sẽ bắt gặp bất kỳ lỗi nào trong các luồng ứng dụng. Thêm một trình xử lý sự kiện trước khi gọi Application.Run.

Câu trả lời thứ hai của bạn chắc chắn là có. Tôi phát triển và duy trì một ứng dụng winforms doanh nghiệp mà nói chuyện với một phụ trợ dịch vụ web trên các chủ đề nền. Nếu bất kỳ sự cố gọi webservice nào xử lý sự kiện ngoại lệ của ứng dụng (và cũng là ngoại lệ appdomain), hãy ghi nhật ký và bật lên một lỗi mà người dùng doanh nghiệp có thể báo cáo và cho phép họ tiếp tục mà không gặp phải ứng dụng.

0

1) Cần loại trừ các ngoại lệ Win32. Có lẽ ngoại lệ đang được ném từ một chủ đề nền hoặc chủ đề GC?

2) Tùy thuộc vào cấu trúc ứng dụng của bạn. Ví dụ: nếu giao diện người dùng thông báo lỗi của bạn được gắn với biểu mẫu chính bằng cách nào đó (ví dụ: bạn cần gọi chuỗi giao diện người dùng từ chuỗi công nhân), thì sẽ rất ngớ ngẩn để hiển thị giao diện người dùng trong khối mã bên ngoài mã chạy thư vòng lặp. Tuy nhiên, nếu ví dụ mã của bạn là đơn luồng thì sẽ ổn thôi.

1

Cố gắng đăng ký vào những sự kiện này trước khi bắt đầu ứng dụng của bạn (Application.Run):

Sau đó, bạn có thể loại bỏ khối try catch của mình.


Tôi nghĩ việc thực hành ngoại lệ ở mức cao nhất là không tốt, nhưng bạn không thể tránh được! Trong quá trình phát triển (Debug), những trường hợp ngoại lệ đó không nên bị bắt và ứng dụng nên thực hiện điều tồi tệ nhất có thể (crash?). Trong quá trình sản xuất (Release), bạn sẽ muốn ứng dụng của bạn bị suy giảm càng tốt càng tốt ngay cả khi các trường hợp ngoại lệ chưa được giải quyết xảy ra. Đây là một trong số ít sử dụng tôi tìm thấy cho số DEBUG preprocessor variable.

+0

Có bạn đi: 2 câu trả lời trong một. Bạn sẽ sử dụng cái nào (hoặc chống lại)? – Mac