질문은 finalize가 호출 될 때 객체가 리소스를 처리한다는 사실을 테스트하는 방법입니다. 클래스에 대한 코드 :테스트 최종 자 및 IDisposable
는public class TestClass : IDisposable {
public bool HasBeenDisposed {get; private set; }
public void Dispose() {
HasBeenDisposed = true;
}
~TestClass() {
Dispose();
}
}
을 유의하시기 바랍니다 난 그냥 지금은 먼저 테스트 할 수있는 방법을 찾아 원하는대로 폐기 /의 Finalize의 올바른 구현에 대해 걱정하지 않는다. 이 단계에서 가정하면 충분합니다. HasBeenDisposed은 Dispose/Finalize가 호출되면 true로 설정됩니다.
[Test]
public void IsCleanedUpOnGarbadgeCollection() {
var o = new TestClass();
o.HasBeenDisposed.Should().Be.False();
**var weak = new WeakReference(o, true); // true =Track after finalisation
o = null; // Make eligible for GC**
GC.Collect(0, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
**((TestClass)weak.Target)**.HasBeenDisposed.Should().Be.True();
}
또는 더 나은 (가 UPDATE 이후에 추가) 좋아하는 코드 :
[Test]
public void IsCleanedUpOnGarbadgeCollection() {
WeakReference weak = null;
// Use action to isolate instance and make them eligible for GC
// Use WeakReference to track the object after finalisaiton
Action act =() = {
var o = new TestClass();
o.HasBeenDisposed.Should().Be.False();
weak = new WeakReference(o, true); // True=Track reference AFTER Finalize
};
act();
GC.Collect(0, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
// No access to o variable here which forces us to use WeakReference only to avoid error
((TestClass)weak.Target).HasBeenDisposed.Should().Be.True();
}
이 테스트 WeakReference를으로 업데이트
:
실제 시험 내가 좋아하는 외모를 썼다 실패 (시동 후 업데이트)하지만 다음을 준수합니다 (업데이트]) :
- GC.WaitForPendingFinalizers()는 스레드를 중단 수행하고 O를 의 인스턴스를 확정,하지만 경우가 뿌리되지 않습니다. 그것에 NULL을 할당하고 WeakReference를 사용하여 종료 후 가져옵니다.
- 이 인스턴스를 보유하지 않을 때 올바른 위치에서 Finilize (소멸자) 코드가 실행됩니다.
그래서 이것을 테스트하는 올바른 방법은 무엇입니까? 나는 무엇을 놓치나요?
나는 변수가 인데, GC가 그것을 수집하지 못하게한다고 가정합니다.
업데이트 : 예, 문제입니다. WeakReference를 대신 사용해야했습니다.
이것은 정확히 내가 필요한 것입니다. 액션 델리게이트를 사용하면 코드가 별도의 스택 프레임에 저장되어 유닛 테스트에서 객체를 올바르게 수집 할 수 있습니다. – NathanAW
이 솔루션을 이용해 주셔서 감사합니다. 나에게 그것은 단순히 원래 변수를 null로 설정하여 대리자없이 작동한다. (편집 : necropost 죄송합니다, 날짜를 알리지 않았다) – amnesia