C# Language
IDisposable 인터페이스
수색…
비고
IDisposable
을 구현하는 클래스의 클라이언트는 개체를 사용하여 마쳤을 때Dispose
메서드를 호출해야합니다.Dispose
메서드를 호출 할 개체를 직접 검색하는 것은 CLR에 없습니다.개체에 관리되는 리소스 만있는 경우에는 finalizer를 구현할 필요가 없습니다. 자신의
Dispose
메소드를 구현할 때 클래스가 사용하는 모든 객체에서Dispose
를 호출해야합니다.이상적으로 한 번만 호출해야하지만
Dispose
에 대한 여러 번 호출에 대해 클래스를 안전하게 만들 것을 권장합니다. 이것은 클래스에private bool
변수를 추가하고Dispose
메서드가 실행될 때 값을true
설정하여 수행 할 수 있습니다.
관리되는 리소스 만 포함하는 클래스
관리 자원은 런타임의 가비지 컬렉터가 알고 있고 통제하고있는 자원입니다. BCL에는 예를 들어 관리되지 않는 리소스의 래퍼 클래스 인 SqlConnection
과 같은 많은 클래스가 있습니다. 이 클래스는 이미 IDisposable
인터페이스를 구현합니다. 완료되면 코드를 정리해야합니다.
클래스에 관리되는 리소스 만 포함되어있는 경우에는 finalizer를 구현할 필요가 없습니다.
public class ObjectWithManagedResourcesOnly : IDisposable
{
private SqlConnection sqlConnection = new SqlConnection();
public void Dispose()
{
sqlConnection.Dispose();
}
}
관리되는 리소스와 관리되지 않는 리소스가있는 클래스
마무리 작업을 통해 관리되는 리소스를 무시하는 것이 중요합니다. 파이널 라이저는 다른 스레드에서 실행됩니다. 파이널 라이저가 실행될 때 관리 대상 객체가 더 이상 존재하지 않을 수도 있습니다. 보호 된 Dispose(bool)
메서드를 구현하는 것은 관리되는 리소스에 Finalizer에서 호출 된 Dispose
메서드가 없도록하는 일반적인 방법입니다.
public class ManagedAndUnmanagedObject : IDisposable
{
private SqlConnection sqlConnection = new SqlConnection();
private UnmanagedHandle unmanagedHandle = Win32.SomeUnmanagedResource();
private bool disposed;
public void Dispose()
{
Dispose(true); // client called dispose
GC.SuppressFinalize(this); // tell the GC to not execute the Finalizer
}
protected virtual void Dispose(bool disposeManaged)
{
if (!disposed)
{
if (disposeManaged)
{
if (sqlConnection != null)
{
sqlConnection.Dispose();
}
}
unmanagedHandle.Release();
disposed = true;
}
}
~ManagedAndUnmanagedObject()
{
Dispose(false);
}
}
IDisposable, Dispose
.NET Framework는 분리 방법이 필요한 유형의 인터페이스를 정의합니다.
public interface IDisposable
{
void Dispose();
}
Dispose()
는 주로 비 관리 참조 같은 리소스 정리에 사용됩니다. 그러나 관리되는 경우에도 다른 리소스를 강제로 폐기하는 것이 유용 할 수 있습니다. GC가 결국 데이터베이스 연결을 정리하기를 기다리는 대신 자신의 Dispose()
구현에서 완료되었는지 확인할 수 있습니다.
public void Dispose()
{
if (null != this.CurrentDatabaseConnection)
{
this.CurrentDatabaseConnection.Dispose();
this.CurrentDatabaseConnection = null;
}
}
관리되지 않는 포인터 또는 win32 리소스와 같은 관리되지 않는 리소스에 직접 액세스해야하는 경우 SafeHandle
에서 상속하는 클래스를 만들고 해당 클래스의 규칙 / 도구를 사용하십시오.
관리 자원이있는 상속 된 클래스에서
IDisposable
을 구현하는 클래스를 만든 다음 관리되는 리소스를 포함하는 클래스를 파생시키는 것이 일반적입니다. 클라이언트가 소유 할 수있는 모든 자원을 정리할 수 있도록 Dispose
메서드를 virtual
키워드로 표시하는 것이 좋습니다.
public class Parent : IDisposable
{
private ManagedResource parentManagedResource = new ManagedResource();
public virtual void Dispose()
{
if (parentManagedResource != null)
{
parentManagedResource.Dispose();
}
}
}
public class Child : Parent
{
private ManagedResource childManagedResource = new ManagedResource();
public override void Dispose()
{
if (childManagedResource != null)
{
childManagedResource.Dispose();
}
//clean up the parent's resources
base.Dispose();
}
}
키워드 사용
객체가 IDisposable
인터페이스를 구현하면 using
구문 내에서 객체를 만들 수 있습니다.
using (var foo = new Foo())
{
// do foo stuff
} // when it reaches here foo.Dispose() will get called
public class Foo : IDisposable
{
public void Dispose()
{
Console.WriteLine("dispose called");
}
}
using
입니다 syntatic 설탕 A의 try/finally
블록; 위의 사용법은 대략 다음과 같이 번역됩니다.
{
var foo = new Foo();
try
{
// do foo stuff
}
finally
{
if (foo != null)
((IDisposable)foo).Dispose();
}
}