갑자기 의존하는 중첩 클래스가 IDisposable
을 구현하는 IDisposable
체인을 깨는 방법을 원했지만 해당 인터페이스가 합성 레이어를 리핑하지 않도록하고 싶습니다. 기본적으로 IObservable<T>
에 약한 구독이 있습니다. 'SubscribeWeakly()'을 통해 내가 래퍼 인스턴스가 누출되지 않도록 정리할 때 정리하려고합니다. Observable
이 실행되지 않습니다. 그것은 동기 였지만 나는 다른 것들에도 사용했다.안전하게 .net finalizer 내에서 처리하십시오.
또 다른 게시물에 비슷한 문제가 있었으며 answer은 기본적으로 최종 자의 소지품에 액세스 할 수 있다고 명시했습니다. 그러나 종료 자의 순서가 보장되지 않으므로 처리가 문제가 될 수 있습니다.
따라서, 나는 일회용품이 살아있게 보장 할 수있는 방법이 필요했기 때문에 파이널 라이저에 Dispose()
을 부를 수있었습니다. 그래서 GCHandle
을 보았습니다. C++이 핸들을 free'd하고 .NET의 컨트롤에 복합 라이프 타임이 돌아올 때까지 계속 유지하기 위해 핸들과 집계를 응용 프로그램 핸들로 가져 와서 관리 대상 객체를 유지하고 유지합니다. 메모리 관리자. C++에서 왔기 때문에 std::unique_ptr
과 비슷한 동작이 좋을 것이라고 생각하여 AutoDisposer
과 비슷한 것을 생각해 냈습니다. 멀리 갈 때 자원을 처리하는 데 필요한 클래스에서
public class AutoDisposer
{
GCHandle _handle;
public AutoDisposer(IDisposable disposable)
{
if (disposable == null) throw new ArgumentNullException();
_handle = GCHandle.Alloc(disposable);
}
~AutoDisposer()
{
try
{
var disposable = _handle.Target as IDisposable;
if (disposable == null) return;
try
{
disposable.Dispose();
}
finally
{
_handle.Free();
}
}
catch (Exception) { }
}
}
, 방금
_autoDisposables = new AutoDisposer(disposables)
같은 필드를 할당합니다. 그런 다음이
AutoDisposer
은 포함 클래스가 수행 할 때와 같이 가비지 컬렉터에 의해 정리됩니다. 그러나이 기술로 어떤 문제점이 있는지 궁금합니다. 지금은 다음을 생각할 수 있습니다 가진 파이 나라에 의해 가비지 컬렉터에
- 추가 오버 헤드
- .NET 응용 프로그램 핸들로 관리되는 메모리에서 항목을 꺼내 필요하고 그들에게
- 하지 반환의 추가 오버 헤드
IDisposable
를 구현하는 부담을 너무 많이하지 않을 때 내가 필요하면 단위 테스트 가능한 (나는 자원이 메모리 관리를 위해 .NET으로 반환됩니다 예측할 수없는 것.) 따라서
, 내가 아껴서 사용 결정적으로에 전화하기등
다른 문제가 있습니까? 이 기술은 유효합니까?
간단한 답 : 모든 소멸자 제거 (종료 자). 잊어 버려. –
_ Dispos() _ _를 호출 할 수 있도록 일회용품이 생존하도록 보장하는 방법이 필요했습니다. 거꾸로 물건을 뒤집습니다. –
당신이 * finalizer 내부에있을 때'IDisposable' (올바르게 구현 된 경우)은 이미 finalizer를 실행하고 finalizer 내에서 합리적으로 기대할 수있는만큼 정리를 수행했을 수 있습니다. 당신의 부름'Dispose'는이 단계에서 도움을 줄 수 없습니다. –