Прочитав
http://tooslowexception.com/do-we-need-jvms-phantomreference-in-net/, не понял одного: почему нельзя построить аналогичное решение на чистых WeakReference-ах?
То есть делаем вот такую штуку:
public abstract class PhantomReference<T>
{
private WeakReference<T> _reference
public PhantomReference(T reference, IFinalizationQueue<T> queue)
{
_reference = new WeakReference<T>(reference ?? throw new ArgumentNullException(nameof(reference)));
(queue ?? throw new ArgumentNullException(nameof(queue)).Add(this);
}
public bool IsDead()
{
T _;
return !_reference.TryGetTarget(out _);
}
public abstract void Finalize();
}
Ну и дальше как бы всё то же самое.
public class SafeHandleReference: PhantomReference<SafeHandle>
{
private IntPtr _handle;
public SafeHandleReference(SafeHandle handle): base(handle, SafeHandleQueue.MainInstance) =>
_handle = handle.GetHandle();
public override void Finalize() => System.FreeHandle(_handle);
}
Вроде бы всё как надо — оживить ссылку нельзя, просохатить событие — тоже негде; полная свобода выбора момента финализации.
Например, можно встроить вызовы очистки SafeHandleQueue.MainInstance во всякие методы классов в System.IO — чтобы периодически освобождать утекающие ссылки.