2009-02-25 5 views
37

IDisposable을 구현하는 C# 클래스를 작성하는 경우 관리되지 않는 리소스를 처리 할 때.NET에서 Dispose (bool disposing)를 무시하는 것이 무엇입니까?

public void Dispose(){ ... } 

을 구현하기 만하면 충분하지 않은 이유는 무엇입니까?

protected virtual void Dispose(bool disposing){ ... } 

는 항상 필요하며, 때로는 필요하거나 다른 무엇입니까?

+0

내 수업에서는 청소가 필요한 관리되지 않는 리소스 만 있고 IDisposable은 정적 분석으로 처리하기 때문에 Dispose (bool disposing)로 보호됩니다. 필자의 경우 "처분"매개 변수는 Finalizer와 Dispose가 똑같은 것을하기 때문에 유용하지 않습니다. – AksharRoop

답변

28

꼭 필요한 것은 아닙니다. 이것은 일회용으로 권장되는 패턴의 일부입니다. 이 프레임 워크 디자인 지침 섹션을 읽지 않은 경우 (초판 9.3 절, 두 번째 버전은 유감스럽게 생각하지 마십시오) 다음과 같이하십시오. Try this link.

일회용 정리와 최종 마무리 가비지 수집 쓰레기 분리를 구분하는 데 유용합니다.

이렇게 할 필요는 없지만이를 읽어야하며 불필요한 것으로 간주하기 전에 권장 이유를 이해해야합니다.

+3

"IDisposable : 어머니가 자원 할당 해제에 대해 말하지 않은 것"에 대한 링크는 너무 아래에 있으므로 여기에서 복사 해 보겠습니다 : http://www.codeproject.com/KB/dotnet/IDisposable.aspx –

+0

FYI bluebytesoftware 위의 첫 번째 연결이 끊어졌습니다. – codenheim

+0

@mrjoltcola 감사합니다, MSDN 링크로 업데이트 됨 (그러나 이것들은 약간 임시 변수가 될 수도 있음) –

3

bool 처리를 사용한 추가 방법은 프레임 워크 설계 지침에서 벗어났습니다. 그것은 클래스가 예외를 던지지 않고 dispose 메소드를 여러 번 호출 할 수있게하는 패턴입니다. 절대적으로 필요한 것은 아닙니다. 엄밀히 말하면 처리 방법에서 처리 할 수 ​​있습니다.

13

MSFT 문서에는 일회용 패턴에 대한 편견이 있습니다. 당신은 종료자를 가지고는 IDisposable

  • 를 구현하는 유형의

    1. 가지고있어 필드 : 당신이는 IDisposable을 구현해야하는 이유는 두 가지가있다.

    사례 1은 대부분의 코드에서 매우 일반적입니다. 사례 2는 마이크로 소프트가 작성한 코드에서 흔히 볼 수있는 사례입니다. 관리 대상 래퍼를 관리되지 않는 리소스 주위에 작성 했으므로 마무리 작업이 필요합니다. 하지만 코드에서 매우 드문 경우 여야합니다. 결국, 당신은 좋은 .NET 클래스를 가지고있어 당신을 위해 더러운 일을 할 수 있습니다. Dispose() 메소드를 호출하면됩니다.

    케이스 2에만 일회용 패턴이 필요합니다. 마이크로 소프트는 그것을 많이 사용해야합니다. 대부분의 경우 간단한 Dispose() 만 있으면됩니다.

  • +0

    내 클래스에서 나는 청소가 필요한 관리되지 않는 리소스를 가지고 있고 IDisposable을 보호 된 가상 void로 구현했습니다. 정적 (bool disposing)은 정적으로 처리합니다. 분석은 그것을 강요합니다. 필자의 경우 "처분"매개 변수는 Finalizer와 Dispose가 똑같은 것을하기 때문에 유용하지 않습니다. – AksharRoop

    +0

    전달할 내용이 무엇인지 확실하지 않습니다. SafeHandle 및/또는 SafeBuffer 래퍼 클래스를 사용하면 잘못했을 수도 있습니다. 중요한 finalizers 좋은 있습니다. 글 머리 기호 1로 돌아 가기. –

    +0

    Ok. 원래 원래 질문은 값이 참이고 값이 거짓 일 때 Dispose (bool disposing)가 수행해야하는 것과 다릅니다. 매개 변수 처분은 무엇입니까? – AksharRoop

    41

    마무리 자, 새 가상 메서드 소개 및 원래 처분 방법의 "봉인"을 포함한 전체 패턴은 모든 기본을 포함하는 매우 일반적인 목적입니다.

    핸들러가 관리되지 않는 리소스 (almostnever이어야 함)에서 처리되는 경우가 아니라면 최종자를 필요로하지 않습니다.

    클래스를 봉인하고 (가능하면 밀봉 클래스에 대한 내 견해는 아마도 지금까지 잘 알려져 있습니다 (design for inheritance or prohibit it) 가상 메소드를 소개 할 필요가 없습니다.

    마지막으로 복잡한 코드를 구현 한 적이 기억이 안납니다.주의 할

    public void Dispose() 
    { 
        somethingElse.Dispose(); 
    } 
    

    한 가지는 당신이 정말로 강력한 코드려고하는 경우에, 당신 당신이 배치 된 한 후에 아무것도하려고하지 않는지 확인해야하고, 적절한 ObjectDisposedException를 던질 것입니다 . 그것은 전 세계의 개발자들이 사용할 클래스 라이브러리에 대한 좋은 조언이지만, 이것이 자신의 작업 공간 내에서 사용되는 클래스 일 경우 거의 이득을 얻지 못합니다. 다른 큰 응답에 추가

    +0

    굉장한 설명 - 그리고 구제! –

    +0

    FYI, bluebyte에 대한 링크가 깨졌습니다. –

    +0

    @HamishSmith : 고마워요. (블로그가 옮겨졌습니다.) –

    1

    그냥 다른 사람들이에 확장 고 말했다 : 그것은 단지 당신이하지 않는 것이 아니다. '복잡한 처리'가 필요하다. 실제로는 을 원하지 않는다. 성능을 위해 자제.

    '복잡한 처리'경로로 이동하여 파이널 라이저를 구현 한 다음 명시 적으로 개체를 삭제하는 것을 잊어 버리면 개체 (및 참조 된 모든 항목)가 실제 처리되기 전에 여분의 GC 생성에서 생존합니다. CLR이 파이널 라이저를 호출하는 데 한 번 더 걸림). 이것은 단지 당신이 필요하지 않은 더 많은 기억 압력을 유발합니다. 또한 객체의 전체 힙에서 finalizer를 호출하는 것은 드문 일이 아닙니다.

    사용자 (또는 파생 된 유형)가 관리되지 않는 리소스를 갖고 있지 않으면 피하십시오.

    아, 우리가이 분야에있는 동안 : 다른 사람들의 이벤트를 처리하는 클래스의 메소드는 클래스가 삭제 된 후에 호출 될 때 '안전'해야합니다. 가장 간단한 방법은 클래스가 삭제 된 경우 no-op를 수행하는 것입니다. http://blogs.msdn.com/ericlippert/archive/2009/04/29/events-and-races.aspx

    1

    최종 결과와 관련없는 Dispose()에서 작업을 수행하고 관리되지 않는 리소스를 정리할 수 있다는 점이 하나 있습니다.

    Doing 최종 사용자의 '자신'이외의 관리 대상에 대한 내용은 ... 예측할 수 없습니다. 이것의 대부분은 finalizer가 무 결정적 방식으로 AppDomain의 2 단계 종료에서 호출된다는 사실 때문에 - finalizer가 호출 될 때 여전히 참조가있는 객체가 이미 완료되었습니다.

    같은 메서드에 대한 Dispose 및 finalizer 호출을 모두 보내면 종료 코드를 공유 할 수 있지만 boolean 매개 변수를 사용하면 관리되는 정리를 건너 뛸 수 있습니다.

    또한 가상 메서드를 사용하면 실수로 자신을 호출하지 않을 위험없이 상속자가 자신의 정리 코드를 쉽게 추가 할 수 있습니다.

    1

    클래스가 IDisposable.Dispose()을 구현하고 파생 클래스가 추가 논리를 추가해야하는 경우 해당 클래스는 파생 클래스가 연결할 수있는 일종의 Dispose 메서드를 노출해야합니다. 어떤 클래스는 public Dispose() 메서드가없는 IDisposable.Dispose()을 구현할 수 있기 때문에 public 메서드가 Dispose인지 여부에 관계없이 IDisposable의 모든 구현에서 protected이 될 가상 메서드를 갖는 것이 유용합니다.대부분의 경우 bool 인수는 실제로 의미가 없지만 protected virtual Dispose(bool)이 공개 또는 공개되지 않을 수도있는 Dispose()과 다른 서명을 갖도록 거짓 인수로 생각해야합니다.

    protected virtual Dispose(bool)을 사용하지 않는 클래스는 규칙과 다른 방식으로 정리 논리를 처리하기 위해 파생 클래스가 필요합니다. 해당 컨벤션을 따르는 IDisposable 구현을 확장 할 수있는 C++/CLI와 같은 일부 언어는 비표준 구현에서 클래스를 파생하지 못할 수 있습니다.