2009-10-16 38 views
17

Giả sử bạn có đoạn mã sau:Xử lý ngoại lệ: Cuối cùng được thực hiện sau khi ném?

Thay vì thực hiện:

Try 
    ' 
    ' Initialize some objects 
    ' 

    ' 
    ' do something that fails 
    ' 

    ' 
    ' Clean up-code that gets not reached because exception 
    ' 
Catch e As Exception 
    ' 
    'Clean up initialized objects 
    ' 

    Throw e 
End Try 

Tôi muốn làm:

Try 
    ' 
    ' Initialize some objects 
    ' 

    ' 
    ' do something that fails 
    ' 
Catch e As Exception 
    Throw e 
Finally 
    ' 
    'Clean up initialized objects 
    ' 
End Try 

Vì vậy, câu hỏi đơn giản của tôi là: Trong trường hợp ngoại lệ là cuối cùng khối đạt được ngay cả khi có một ném một số dòng trước?

[EDIT] Cảm ơn câu trả lời nhanh của bạn.

Trong dòng đầu tiên sẽ có NullReference-, COM- và FileNotFound-Exceptions tôi nghĩ.

Ok, tôi sẽ đi cho mã này:

Try 
    ' 
    ' Initialize some objects 
    ' 

    ' 
    ' do something that fails 
    ' 
Catch e As Exception  ' or just "Catch"??   
    Throw 
Finally 
    ' 
    'Clean up initialized objects 
    ' 
End Try 

Tất cả là tốt nhất!

Inno

+2

Bạn không nên viết 'Ném e' mà chỉ là' Ném '. Nếu không, bạn đặt lại dấu vết ngăn xếp ngoại lệ, vì vậy bạn sẽ mất thông tin về nơi ngoại lệ được nêu ban đầu –

Trả lời

25

Vì vậy, câu hỏi đơn giản của tôi là: Trong trường hợp ngoại lệ là khối finally đạt thậm chí nếu có một ném một số dòng trước?

Có. Finally blockluôn luôn1) được thi hành và tồn tại chính xác để làm sạch. Trong mã của bạn, hãy xóa khối Catch, không có gì. Tệ hơn nữa, nó thực sự phá hủy dấu vết ngăn xếp bởi vì bạn không ném lại ngoại lệ ban đầu, bạn ném một ngoại lệ mới.

Nếu bạn thực sự cần một khối Catch mà sau đó lại ném ngoại lệ, sử dụng như sau:

Catch e As XyzException 
    ' … do some stuff. ' 
    Throw 
End Try 

1): emptor Nên biết trước: có một số trường hợp ngoại lệ như StackOverflowException (làm thế nào phù hợp ...) cần chú ý đặc biệt và có thể không kích hoạt khối Finally. Xử lý chúng một cách chính xác thường khá khó khăn.

+1

Konrad - Cuối cùng không phải lúc nào cũng được thực thi. Nó sẽ không được thực hiện khi bạn có một OutOfMemoryException ví dụ. –

+0

@Pete: đúng, nhưng đây là những trường hợp cạnh cụ thể (nhưng tôi nên đã đề cập đến chúng). –

+1

@Pete: Bạn không có nghĩa là StackOverflowException. Nó là yên tĩnh dễ dàng để thực hiện một thử nghiệm mà cuối cùng là chạy trong trường hợp của một OutOfMemoryException. –

0

Có, cuối cùng cũng được thực hiện trong mọi trường hợp. (chỉ có vài ngoại lệ - Response.Redirect và một số trường hợp có đa luồng)

5

Không, nó KHÔNG được bảo đảm để chạy. Có một số ngoại lệ nhất định - ví dụ StockOverflowException và OutOfMemoryException - nơi việc thực thi khối cuối cùng không được đảm bảo.

1

Trong hầu hết các trường hợp, cuối cùng sẽ thực hiện trong khối Thử/Bắt (ngoại lệ đáng chú ý bao gồm khi xảy ra StackOverflowException hoặc OutOfMemoryException). Tôi tò mò mặc dù, tại sao bạn không thử điều này cho chính mình. Một cách có giá trị để học hỏi mọi thứ là thực sự thử chúng cho bản thân bạn - rốt cuộc, bạn có thể chấp nhận câu trả lời sai hoặc gây hiểu lầm, và bạn sẽ lao động dưới sự sai lầm này từ thời điểm đó.

+1

Tôi đã thử điều này nhưng trình gỡ lỗi của tôi dừng lại ở chế độ ném. Tôi đọc tài liệu và không tìm thấy gợi ý cho câu hỏi của tôi. Tôi hỏi những câu hỏi này để có được câu trả lời thuộc về câu hỏi của tôi và thuộc gián tiếp với nó (như gợi ý như "cuối cùng là trong những trường hợp đặc biệt không được thực hiện"). – Inno

1

GHI CHÚ: Phương thức System.Environment.FastFail đã hủy quá trình hiện tại/luồng ngay lập tức, mà không thực thi các phần cuối cùng.

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