관리되지 않는 리소스를 "소유"하는 클래스는 무엇입니까(그리고 IDisposable을 구현하는 클래스는 무엇입니까)?

StackOverflow https://stackoverflow.com//questions/9657637

문제

나는 일하고있다 OSS 프로젝트 대중화시키려고 미디어정보 라이브러리 .NET에서 사용하기가 더 쉽지만 이 질문은 일반화 가능합니다.

파생 클래스인 경우 항상 객체를 인스턴스화합니다. 영형 기본 클래스를 호출할 때 DB의 생성자입니다.DB는 생성자에게 전송된 값으로 값을 설정하지만 값 자체는 다음에서 선언됩니다. DB의 기본 클래스 :

  1. 누가 "소유"합니까? 영형 (아래 코드의 mediaInfo라고도 함)?
  2. .NET 애플리케이션의 경우 다음 중 IDisposable을 구현해야 하는 것은 무엇입니까?메모: 영형 관리되지 않거나 최소한 관리되지 않는 라이브러리를 둘러싸는 관리되는 객체의 인스턴스화이지만 "미디어정보.닫기();".이것이 "관리되지 않음"으로 간주되는지 확실하지 않습니다.

명확히 하기 위해 실제 코드를 사용해 보겠습니다.

~에서 얻다 DB:

// MediaFile is "D" 
public sealed class MediaFile : GeneralStream
{
    public MediaFile(string filePath)
        : base(new MediaInfo(), 0) {
        // mediaInfo is "O"
        mediaInfo.Open(filePath);
    }
}

DB 상속된 항목을 설정합니다. 영형, 로부터 나오다 :

// GeneralStream is "DB"
public abstract class GeneralStream : StreamBaseClass
{
    public GeneralStream(MediaInfo mediaInfo, int id) {
        this.mediaInfo = mediaInfo; // declared in StreamBaseClass
        // ...
    }
}

선언하다 영형:

// StreamBaseClass is "B"
public abstract class StreamBaseClass
{
    protected MediaInfo mediaInfo; // "O" is declared
    // ...
}
도움이 되었습니까?

해결책

리소스에 대한 참조를 보유하는 개체가 이를 소유합니다.

StreamBaseClass 참조가 있습니다 mediaInfo 그리고 구현해야 IDisposable.참고자료와 Dispose 메소드는 파생 클래스에 의해 자동으로 상속됩니다.

다른 팁

클래스 C가 IDisposable을 구현하는 로컬 변수 V 인 변수를 소유하고 있으면 C가 IDisposable이어야하며 C의 IDisposable은 v.

클래스 D가 기본 자원 N을 소유 한 다음 D가 IDisposable (n)을 idisable해야하며 도 릴리스하기 위해 폐기 할 수있는 최종 소멸자가 있습니다.

이 패턴을 따르면 IDisposable이있는 경우 완료되면 항상 () 항상 객체 트리 아래로 모든 것을 삭제합니다.그러나 누군가가 당신을 잊어 버린 경우 (읽기 : 동료, 사용자의 라이브러리 사용자 등)은 기본 자원이 d 's finalizer에 의해 정리되므로 객체가 누출되지 않습니다.

책임 IDisposable 그 물건에 속한다. 창조하다 달리 명시적인 합의가 없는 경우.반대 계약은 일반적으로 리소스 작성자가 소비자의 수명을 전혀 모르는 경우에 사용됩니다.나는 많은 경우에 생성자나 팩토리 메소드가 전달된 객체의 마지막 소비자가 될 수 있는 것을 생성할 때 다음을 제안하고 싶습니다. IDisposable, 해당 메소드는 호출에 대한 책임을 수락해야 하는지 여부를 나타내는 매개변수를 수락해야 합니다. Dispose, 그렇지 않으면 null이 아닌 경우 소비자에게 더 이상 객체가 필요하지 않을 때 호출되는 콜백 대리자를 수락합니다.개체 작성자가 소비자보다 오래 지속되는 경우 null을 전달할 수 있습니다.객체가 전달된 후 작성자가 객체를 더 이상 사용할 수 없는 경우 객체의 Dispose 방법.작성자가 소비자보다 오래 지속될지 여부를 모르는 경우 개체가 여전히 필요한지 확인하는 메서드를 전달하고 호출할 수 있습니다. Dispose 그렇지 않다면.

귀하의 특정 사례와 관련하여 IDisposable 연결된 생성자 호출 내에는 리소스 누수에 대한 방법이 있습니다(연결된 생성자 호출을 try-finally 블록으로 래핑할 방법이 없기 때문입니다).어떻게든 안전하게 처리하려면(예:연결된 생성자 대신 팩토리 메소드를 사용하거나 [threadstatic] hack), 객체 생성자(파생 클래스)가 소비자(기본 클래스)의 수명을 알 것이므로 소유권과 정리 책임은 객체 생성자에게 있어야 한다고 제안하고 싶습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top