2013-08-05 28 views
7

Có nhiều câu hỏi (1, 2, 3, 4 v.v.) được gọi là "Tại sao ngoại lệ này không bị bắt". Đáng buồn thay, không có giải pháp nào làm việc cho tôi ... Vì vậy, tôi bị mắc kẹt với một ngoại lệ thực sự không thể sửa chữa được.Moby Dick của ngoại lệ

Tôi có một đoạn mã (.NET 4.0) kiểm tra một tệp văn bản lớn cho các chữ số và số. Trong khi thử nghiệm tôi nhận được một ngoại lệ thời gian chạy:

Exception

Những gì bạn thấy ở đây là một mô hình try-catch với một catchblock cho một ArgumentOutOfRangeException. Nhưng trong thời gian chạy, khối try ném một ArgumentOutOfRangeException mà không bị bắt.

Tôi đọc phần C# language specification về cấu trúc try-catch, và nó nói:

Một khối catch của một câu lệnh try có thể truy cập nếu câu lệnh try có thể truy cập.

Vì vậy, trong lý thuyết, mã trên phải bắt ngoại lệ. Sau đó tôi nghĩ rằng nó có thể có một cái gì đó để làm với thực tế là mã này đang chạy trong một nhiệm vụ (trong quá trình xử lý của textfile tôi cũng muốn cập nhật giao diện người dùng vì vậy tôi làm điều đó không đồng bộ).. Tôi tìm kiếm xung quanh và sau đó tôi tìm thấy this câu trả lời của Jon Skeet. Về cơ bản cho thấy tôi sử dụng Task.Wait trong một khối try-catch để bắt bất kỳ ngoại lệ nào.

Vấn đề tôi đang gặp phải hiện tại là tôi không thể gọi Task.Wait vì điều đó sẽ chặn chuỗi gọi là chuỗi giao diện người dùng của tôi! Sau đó, tôi đoán rằng tôi có thể tạo ra một tasklayer thêm để chờ đợi cho nhiệm vụ đó:

//Code called from the UI 
System.Threading.Tasks.Task.Factory.StartNew(()=> 
{ 
    //Create a new task and use this task to catch any exceptions 
    System.Threading.Tasks.Task task = System.Threading.Tasks.Task.Factory.StartNew(MethodWithException); 
    try 
    { 
     task.Wait(); 
    } 
    catch(Exception) 
    { 
     MessageBox.Show("Caught it!"); 
    } 
}); 

Nhưng điều này vẫn cho kết quả tương tự ... Sau đó, tôi nghĩ rằng nó có thể là vì thực tế tôi không đủ với cụ Loại trừ của tôi. Nhưng Thông số kỹ thuật ngôn ngữ C# nêu rõ:

Một số ngôn ngữ lập trình có thể hỗ trợ các ngoại lệ không thể đại diện cho đối tượng có nguồn gốc từ mã C#.

Vì vậy, trừ khi bạn sử dụng một số API bên thứ ba sơ sài, bạn luôn luôn tốt khi bạn sử dụng Exception. Vì vậy, tôi thấy mình với một câu trả lời được đề xuất bởi Jon Skeet mà không hoàn toàn làm việc cho tôi. Đó là khi tôi biết tôi chỉ nên ngừng thử ...

Vì vậy, không ai biết điều gì đang xảy ra? Và làm thế nào tôi có thể sửa lỗi này? Tôi biết tôi chỉ có thể kiểm tra nếu i bằng hoặc lớn hơn text.Length nhưng hiểu được điều gì đang xảy ra quan trọng hơn mã làm việc.

+1

Nó cũng không bị mất mà không có một cơ thể 'catch' trống rỗng? –

+2

Bạn có chắc chắn 100% rằng ngoại lệ đó không được giải quyết? Có thể bạn chỉ cần thiết lập tùy chọn để phá vỡ bất kỳ trường hợp ngoại lệ trong Visual Studio? – Andrey

+2

Bạn đã thử chạy chương trình bên ngoài IDE VS chưa? – Steve

Trả lời

7

Đây chỉ đơn giản là một tạo phẩm của trình gỡ lỗi.

Trong Debug trình đơn, có một tùy chọn gọi là Exceptions... Click vào nó, và chắc chắn rằng để bỏ chọn các "Ném" hộp kiểm ở đây:

exceptions

Nhiều lần, bạn sẽ muốn xem lỗi trong ngữ cảnh, ngay cả khi nó nằm trong một số try/catch, đó là cài đặt này. Trong trường hợp này, đó là chính xác những gì bạn nên làm, để bạn có thể thấy so sánh i với độ dài text và xem vấn đề của bạn ở đâu.

Nếu bạn chạy mã mà không có trình gỡ lỗi (chẳng hạn như bằng cách nhấp đúp vào tệp thực thi hoặc sử dụng tùy chọn "Bắt đầu mà không gỡ lỗi"), bạn sẽ "xóa" một cách chính xác mà không có bất kỳ cảnh báo nào.

+0

Tại sao VS của tôi không liệt kê cột do người dùng xử lý? Có phải vì tôi đang sử dụng phiên bản Express không? – nawfal

+0

Đã hiệu quả! Cảm ơn bạn! Nhưng tại sao anh ta không làm điều này cho mọi ngoại lệ Thrown? Tôi tự hỏi làm thế nào hộp kiểm này đã được kiểm tra bởi vì nó không phải là mặc định trong các dự án khác của tôi ... – Jordy

+1

@nawfal - Xem [câu hỏi này] (http://stackoverflow.com/questions/2631305/visual-studio-what-happened- to-the-break-khi-một-ngoại lệ-là-unhandled-optio). – Bobson

0

Tôi chỉ viết những bài kiểm tra sau:

[TestMethod] 
    public void ArgumentOutOfRangeExceptionTest() 
    { 
     string test = "abc"; 
     int i = 0; 
     try 
     { 
      while (true) 
      { 
       test.ElementAt(i); 
       i++; 
      } 
     } 
     catch (ArgumentOutOfRangeException) 
     { } 
    } 

Nó đang làm việc tốt. Tôi tin rằng bạn có một ngoại lệ khác, không được gọi trong mã gọi điện của bạn.

Chỉ có một ngoại lệ mà tôi biết không thể bị phát hiện. Đó là số StackOverflowException. Xem this question về điều đó.

+0

Tôi nghĩ rằng 'ExecutingEngineException' không thể bị bắt. – xanatos

+0

Ảnh chụp màn hình mô tả rõ ràng rằng một ArgumentOutOfRangeException được tô sáng. Tại sao bạn nghĩ rằng nó sẽ là một StackOverflowException thay thế?Câu hỏi bạn đã liên kết không đề cập đến bất kỳ điều gì về điều này. –

+0

"Tôi tin rằng bạn có một ngoại lệ khác", làm thế nào nó có thể khác với những gì màn hình in nói? Hay ý bạn là gì? – Jordy

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