2009-09-15 6 views
4

표준 Dispose 패턴을 살펴 봤는데 관리 리소스를 무료로 만들기 위해 무엇을 써야하는지 궁금합니다. 이러한 자원이 이미 '관리'되어 있다면 확실하게 아무것도 할 필요가 없습니다.관리 리소스는 언제 관리해야합니까?

그렇다면 내 클래스는 관리되지 않는 리소스를 보유하지 않으므로 (따라서 GC로 마무리 할 필요가 없음) 내 Dispose 메서드에서 마무리를 억제하면됩니까? -

public void Dispose() 
{ 
    GC.SuppressFinalize(this); 
} 

그래서 가정이 내 클래스 :

public sealed class MyClass : IDisposable 
{ 
    IList<MyObject> objects; // MyObject doesn't hold any unmanaged resource 
    private bool _disposed; 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    private void Dispose(bool disposing) 
    { 
     if (!_disposed) 
     { 
      // do I need to set the list to null and 
      // call Dispose on each item in the list? 
      if (disposing) 
      { 
       foreach (var o in objects) 
        o.Dispose(); 

       objects = null; 
      } 
     } 

     _disposed = true; 
    } 

    ~MyClass() 
    { 
     Dispose(false); 
    } 
} 

실제로 여기에 관리되는 리소스를 해제해야합니까? 클래스, 당신은 관리되는 리소스를 사용하고있는 IDisposable 인스턴스를 포함하며, 따라서 당신은 사용자가 리소스를 처리 할 수 ​​있도록 IDisposable를 구현해야

답변

4

경우

감사합니다. Dispose 메서드는 관리되는 리소스에서 Dispose으로 호출해야합니다.

관리 메모리를 해제하는 데는 아무 것도 할 필요가 없습니다. 이는 GC에 의해 처리되지만 GC에 의해 처리되는 정리의 유일한 부분입니다. 관리되는 리소스와 관리되지 않는 리소스는 Dispose 및/또는 finalizers에 의해 정리되어야합니다.

관리되는 리소스 또는 관리되지 않는 리소스를 사용하지 않는 경우 IDisposable이나 최종자를 구현할 필요가 없습니다. 파이널 라이저 구현은 실제로 유형의 성능에 영향을 미치므로 필요하지 않으면 구현하지 마십시오.

+0

감사 브라이언, 그것은에 도움이 될 것입니다 IDisposable 인터페이스를 구현하고 GC가 인스턴스를 마무리하지 못하도록 Dispose 구현에서 SuppressFinalize (this)를 호출하면됩니까? – theburningmonk

+0

정리 작업이 없다면 IDisposable을 구현하면 어떤 이점이 있습니까? 나는 IDisposable가 때때로 입력/종료 컨텍스트 구조를 구현하는 데 사용된다는 것을 알고 있지만 IMO는 IDisposable/finalizers의 사용을 둘러싼 명백한 혼란에만 추가됩니다. –

+1

@theburningmonk : GC는 명시 적으로 파이널 라이저를 구현하지 않은 이상 오브젝트를 파이널 라이즈하지 않습니다. 아니요, 그냥'SuppressFinalize'를 호출하기 위해'IDisposable'을 구현할 필요가 없습니다. – LukeH

3

IDisposable을 구현하는 관리 대상 개체는 모두 삭제해야합니다.

IDisposable을 구현하지 않는 개체에 Dispose을 호출 할 수 없으므로 확인해야합니다. (MyObject의 모든 가능한 인스턴스/자손은 항상 IDisposable을 구현한다면 분명히, 당신은 그 수표를 필요가 없습니다.)

null에 목록 자체를 설정할 필요가 없습니다.

if (disposing) 
{ 
    foreach (var o in objects) 
    { 
     var d = o as IDisposable; 
     if (d != null) d.Dispose(); 
    } 
} 

(그건 그렇고, 당신의 클래스가 실제로 IDisposable 개체 또는 관리되지 않는 리소스를 보유하지 않는 경우

일반적인 경우

, 아마 이런 식으로 뭔가를 찾기 위해 루프를 다시 써서 IDisposable 또는 finalizer를 구현할 필요가 없을 것입니다.)

1

IDisposable을 구현하는 데는 두 가지 이유가 있습니다.
1. UN 관리 자원을 확보하려면 다음을 수행하십시오. 이 사례는 매우 드물지만 유감스럽게도 많은 의사가 이야기하고 있습니다. 이것은 누출 된 리소스/메모리를 피하는 것, 즉을 무료로하는 것입니다.
2. MANAGED 리소스를 비우려면 다음을 수행하십시오. 이것은 일반적입니다. 즉, 무엇이 해제되는지 확인하는 것이 아니라 (관리되는 리소스가 GC에 의해 항상 해제 될 것이므로) 일이 언제 해제 될지에 대해입니다. 즉, 관리 된 리소스를 해제 할 때 (예 : 소켓이나 파일 등을 닫을 때) 개체 제어 권한을 사용자에게 부여하여 다른 것들을 얻을 수 있도록하는 것입니다.귀하의 경우에는

다음 minimum dispose 제공되지 파생 클래스가 관리 할 수없고 추가합니다 자원을 멀리 얻을 수 있습니다 : 내 수업은 어떤 관리 또는 관리되지 않는 리소스를 사용하지 않는 경우에도

public virtual void Dispose() { 
    foreach (var o in objects) { 
     var d = o as IDisposable; 
     if (d != null) d.Dispose(); 
    } 
} 
관련 문제