[C#] Dispose VS Finalize

|


보통 클래스를 만들때 Dispose나 Finalize를 잘 구현하지는 않습니다.

하지만 필요에 따라서는 구현이 필요할 때가 존재합니다.



1.차이점



클래스 인스턴스에서 관리되지 않는(unmannaged resource) 리소스들(DB 접속, 파일관리등)을 캡슐화할 때가 존재합니다.

해당 인스터스가 종료될 때 이 리소스를 해제하는 명시적인 방법(Dispose)암시적인 방법(Finalize)을 모두 제공되어야 합니다.


보통은 해당인스턴스가 더이상 참조 되지 않을때 GC가 자동적으로 Finalize를 호출해서 리소스를 해제합니다.

하지만 GC에 인스턴스가 수집되기전에 프로그래머가 해제할 수도 있습니다. 이런 경우는 해당 리소스가 드물거나

비싼경우에 명시적으로 Dispose를 호출해서 해제하면 성능이 향상될 수 있습니다.


Dispose를 사용해서 명시적 제어 기능을 제공하더라도 Finalize 을 사용한 암시적으로 정리하는 기능을 제공해야합니다.

프로그래머가 Dispose를 호출하지 못했을때 리소스 누수가 발생하지 않도록 백업하는 기능을 합니다.




2.예제소스


//base class
public class Base: IDisposable
{
    private bool disposed = false;

    //IDisposable 인터페이스 구현
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                //관리되는 자원을 해제
            }
            //관리되지 않는 자원을 해제
            //큰 변수들을 null로 설정한다.
            disposed = true;
        }
    }

    // 소멸자 구현
    ~Base()
    {
        // Simply call Dispose(false).
        Dispose (false);
    }
}

// base class를 상속받는 클래스에서의 dispose 구현
public class Derived: Base
{
    private bool disposed = false;

    protected override void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                //관리되는 자원 해제
            }
            //관리되지 않는 자원해제
            //큰 변수들을 null로 설정한다.
            disposed = true;
        }
        //기본클래스의 dispose 호출
        base.Dispose(disposing);
    }

   //위의 Derived클래스에서는 Finalize와 Dispose()가 구현이 안되어 있는데
   //이것은 base클래스에서상속받는다.
}



3.소스분석

base class에서는 IDisposable 인터페이스를 구현해서 dispose를 구현합니다.

CASE 1 - 프로그래머가 명시적으로 Dispose를 호출해서 자원을 해제한다고 한다면, 우선 Derived 클래스의 인스턴스에서
Dispose()를 호출하게 됩니다. 이때 상속받은 base클래스의 메서드가 실행되면서 Dispose(true) 로 관리되는 자원과 관리되지 않는
자원이 모두 해제가 되며  GC.SuppressFinalize(this); 이 구문으로 가비지컬렉터에서 Finalize가 호출되지 않게 처리합니다.

CASE 2 - 프로그래머가 명시적으로 Dispose를 호출하지 못한다면, base클래스의 소멸자가 호출이되고  Dispose (false); 구문에서
관리되지 않는 자원만 해제가 됩니다.


참고(MSDN) https://msdn.microsoft.com/ko-kr/library/vstudio/b1yfkh5e(v=vs.100).aspx


And