2012-09-03 42 views
8

Nếu tôi có một khối sử dụng xung quanh câu lệnh try catch, điều gì sẽ xảy ra với đối tượng bên trong câu lệnh sử dụng đó thì việc bắt lửa có phải là ngoại lệ không? Hãy xem xét mã sau:Sử dụng câu lệnh với try catch. Điều gì sẽ xảy ra với việc sử dụng câu lệnh?

using (IDatabaseConnectivityObject databaseConnectivityObject = new DbProviderFactoryConnectionBasicResponse()) 
{ 
    try 
    { 
     Foo(); 
    } 
    catch (ArgumentNullException e) 
    { 
     throw; 
    } 
} 

Nếu chúng tôi giả định Foo() không thành công và ngoại lệ được kích hoạt và phá vỡ hiệu quả chương trình sẽ cơ sở dữ liệuKết nối? Lý do quan trọng là đối tượng có kết nối cơ sở dữ liệu liên kết với nó.

Trả lời

9

Bạn có thể nghĩ về số using dưới dạng viết tắt để thử cuối cùng. Do đó mã của bạn là tương đương với:

IDatabaseConnectivityObject databaseConnectivityObject = new DbProviderFactoryConnectionBasicResponse(); 
try 
{ 
    try 
    { 
     Foo(); 
    } 
    catch(ArgumentNullException e) 
    { 
     throw; 
    } 
} 
finally 
{ 
    if(databaseConnectivityObject != null)//this test is often optimised away 
    databaseConnectivityObject.Dispose() 
} 

Nhìn theo cách này, bạn có thể thấy rằng Dispose() sẽ thực sự được gọi là nếu ngoại lệ ném, bởi vì thử-cuối cùng là bên ngoài của try-catch.

Đây chính là lý do chúng tôi sử dụng using.

+0

Cảm ơn Jon. Ví dụ mã của bạn làm cho nó rất rõ ràng. – CSharpened

7

chúng tôi giả định Foo() không thành công và trường hợp ngoại lệ được kích hoạt và hiệu quả vi phạm chương trình sẽ cơ sở dữ liệuKết nốiĐược xử lý?

Có. sử dụng trong nội bộ sử dụng try-finally, (sử dụng chỉ có tác dụng đối với những người mà thực hiện IDisposable)

Từ MSDN- using statement

Việc sử dụng tuyên bố đảm bảo rằng Dispose được gọi thậm chí nếu một ngoại lệ xảy ra trong khi bạn đang phương pháp gọi trên đối tượng. Bạn có thể đạt được kết quả tương tự bằng cách đặt đối tượng vào trong khối thử và rồi gọi Vứt bỏ trong một khối cuối cùng; trên thực tế, đây là cách câu lệnh sử dụng được dịch bởi trình biên dịch.

+0

Vì vậy, có hiệu quả việc sử dụng đang nói thử tất cả các mã trong khối sử dụng và cuối cùng gọi MyObject.Dispose() trong khối cuối cùng mà chúng ta không thấy? – CSharpened

+1

@CSharpened, hoàn toàn đúng, đó là trường hợp. bạn có thể xem ví dụ chi tiết hơn về liên kết trong câu trả lời – Habib

3

Có khối using của bạn sẽ vứt bỏ cơ sở dữ liệuKết nốiĐối tượng, bất kể bạn có khối try-catch hay không.

Bạn phải nói rằng khối sử dụng là quan trọng và bạn nên sử dụng nó cho tất cả các lớp thực hiện IDisposable để đảm bảo rằng chúng được xử lý đúng ngay cả trong trường hợp ngoại lệ.

Từ MSDN- using statement

Việc sử dụng tuyên bố đảm bảo rằng Dispose được gọi thậm chí nếu một ngoại lệ xảy ra trong khi bạn đang gọi phương pháp trên đối tượng. Bạn có thể đạt được kết quả tương tự bằng cách đặt đối tượng vào trong khối thử và rồi gọi Vứt bỏ trong một khối cuối cùng; trên thực tế, đây là cách câu lệnh sử dụng được dịch bởi trình biên dịch.

3

Khi thực hiện chặn using đối tượng trong dấu ngoặc đơn sẽ được xử lý nếu nó triển khai giao diện IDisposable.

Nó vẫn sẽ được xử lý ngay cả khi foo() không thành công.

Đối tượng bên trong câu lệnh sử dụng phải triển khai giao diện IDisposable.

Ngoài ra, các câu hỏi này "Uses of using in c sharp""using statement vs try finally" nói thêm về cách sử dụng và tính thực tiễn của tuyên bố using.

Mục 8.13 trong số C# Language Specification nêu rõ chi tiết câu lệnh sử dụng.

2

đang using của bạn là tương đương với

IDatabaseConnectivityObject databaseConnectivityObject = new IDatabaseConnectivityObject(); 
try 
{ 
//To do code here 
} 
finally 
{ 
    if(databaseConnectivityObject!=null) 
    { 
     databaseConnectivityObject.Dispose(); 
    } 
} 

Một tuyên bố sử dụng chủ yếu là phân loại thành ba phần ví dụ:

  1. Acquisition
  2. Cách sử dụng
  3. Xử

Thứ nhất, các tài nguyên được thu nhận và việc sử dụng được thực hiện trên khối thử với lệnh cuối cùng. Cuối cùng, đối tượng được xử lý trong khối cuối cùng như được đưa ra trong mã tương đương ở trên ...

+1

Tôi nghĩ rằng nó có giá trị chỉ ra rằng kiểm tra null thường được tối ưu hóa đi khi nó có thể được, khi giải thích nó. Một người nào đó có thể bị cám dỗ để làm thử nghiệm riêng của họ - cuối cùng là một tối ưu hóa vi mô. Dù sao thì đó cũng là một ý tưởng tồi tệ (việc giảm mức độ dễ đọc sẽ không đáng giá), nhưng thực tế là nó thậm chí sẽ không mang lại lợi ích nhỏ bé mà họ nghĩ rằng nó có thể, sẽ ngăn cản nó hơn nữa. –

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