2009-07-07 2 views
4

ExecuteReader이 예외를 throw하면 IDataReader이 처분되는 다음 코드 조각에서 어떻게 확인할 수 있습니까?using 문이 예외를 throw하면 IDisposable 개체를 어떻게 처리합니까?

using (IDataReader rdr = cmd.ExecuteReader()) 
{ 
    // use it 
} 

그것은 (그것을 호출 할 인스턴스가 존재하지 않기 때문에)에 using syntatic 설탕 폐기를 호출하지 않습니다 나에게 의미가 있습니다. 그러나 IDisposable을 구현하는 클래스에 의해 일반적으로 할당되는 부족한 리소스가 해제 될 것이라는 것을 어떻게 확신 할 수 있습니까?

+5

ExecuteReader가 예외를 throw하면 IDataReader는 null이며 처리 할 필요가 없습니다. ExecuteReader 내의 관리되지 않는 리소스는 정리가 필요하므로 자체 finally 블록에서 처리해야합니다. – cjk

답변

14

예에서 ExecuteReader가 예외를 throw하면 아무 것도 반환하지 않습니다. 예외 처리 전에 생성 된 모든 것을 처리하는 것은 ExecuteReader의 구현에 달려 있습니다.

+0

그렇기 때문에 예외가 발생하면 예외 처리기가 정리 작업을 수행해야합니다. – jpoh

+3

@jpoh - ** ** 호출자에게는 정리하려고하는 객체가 없습니다. 최악의 경우, 파이널 라이저가 시작됩니다. –

-2

내가 사용하는 문이 유사하다 IL로 번역 된 생각 : 그래서

try 
{ 
} 
finally 
{ 
    disposableUsedObject.Dispose(); 
} 

, 나는 정상적인 상황에서 폐기가 호출되어야한다고 생각?

에 예외를 던져서도 안됩니다. 사용자가 개체를 인스턴스화 할 때 예외가 발생한다고 예상하지 않기 때문입니다. 개체를 인스턴스화 한 후에 호출해야하는 다른 메서드 (초기화)에 예외를 throw 할 수있는 초기화 논리를 옮깁니다.

+1

그러나 생성자가 예외를 throw하면 처리 할 개체가 없습니다. – cjk

+0

@ck 정확히 내 문제 – jpoh

+0

약간 예상치 못한 예외이므로 예외를 생성자에 던져서는 안됩니다. 클래스 사용자는 생성자 안에서/객체를 인스턴스화 할 때 예외가 발생할 수 있다고 예상하지 않습니다. :) 나는 그 초기화 논리를 옮기는 것이 더 낫다고 생각한다. (다른 방법 (초기화 등)을 예외로 삼을 수있다.) –

3

개체의 생성자가 실행되지 않으면 삭제해야 할 개체가 없습니다.

예외를 throw 할 수있는 생성자를 작성하는 경우 using 또는 try-catch 블록을 사용하여 필요한 내용을 정리하는 것이 좋습니다.

IDataReader 예제에서 cmd.ExecuteReader() 메서드 호출이 실패하면 명령 개체를 처리하기 만하면됩니다.

+0

매트가 말한 것을 분명히하기 위해 일회용 클래스의 생성자를 사용하여/try를 사용하여 내부 리소스를 적절히 처리하도록하십시오. 리소스가 클래스 수준 리소스가 아니라 생성자 수준이 될 수 있기 때문에 try catch에 더 기울어 져 있습니다. 그렇다면 사용하는 것이 더 적절합니다. –

0

생성자 외부에서 초기화를 수행하는 코드를 별도의 함수로 옮기는 방법은 어떻습니까? 본질적으로 가질 게

using (var tc = new TestClass()) 
{ 
    tc.Initialize(); // setup the object. acquire expensive resources here, etc. 

    ..more code .. 
} 
+0

이것은 필요하지 않습니다. 다시 말하지만, 생성자가 throw하는 경우 정리할 것이 없습니다. –

관련 문제