Вопрос в том, как я могу проверить, что объект распределяет ресурсы при вызове finalize. Код класса:Тестирование финализаторов и IDisposable
public class TestClass : IDisposable {
public bool HasBeenDisposed {get; private set; }
public void Dispose() {
HasBeenDisposed = true;
}
~TestClass() {
Dispose();
}
}
Обратите внимание, что я не забочусь о правильном выполнении Dispose/Finalize только сейчас, когда я хочу, чтобы найти способ, чтобы проверить его первым. На этом этапе достаточно принять значение . HasBeenDisposed будет установлен в true, если вызывается утилита Dispose/Finalize.
Действительное тест, который я написал, как выглядит:
ОБНОВЛЕНО С WeakReference:
[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();
}
Этот тест (ПРОСМОТРЕТЬ ПОСЛЕ ОБНОВЛЕНИЯ), но я наблюдаю за следующим (ОБНОВЛЕНО):
- GC.WaitForPendingFinalizers() делает приостановить поток и дорабатывает экземпляр в о, но только если не укоренились. Назначил NULL к нему и использовал WeakReference, чтобы получить его после завершения.
- Код завершения (деструктор) выполнен в правильной точке, когда o не имеет экземпляра.
Итак, какой правильный способ проверить это. Что мне не хватает?
Я полагаю, что это переменная о, который предотвращает GC из коллекции его.
ОБНОВЛЕНИЕ: Да, это проблема. Пришлось использовать WeakReference.
Это было именно то, что мне нужно. Ваше использование делегата Action получило мой код в отдельный стек стека и позволило моему модульному тесту правильно собирать объекты. – NathanAW
Спасибо за это решение, он отлично работает. Для меня это работает без делегата, просто устанавливая исходную переменную в значение null. (изменить: извините за некропость, не заметили дату) – amnesia