Answer
Dispose is deterministic cleanup you call; a finalizer runs non-deterministically during GC as a safety net. Finalizers delay collection, so prefer Dispose and suppress finalization.
~Handle() { ReleaseNative(); } // last resort
public void Dispose() { ReleaseNative(); GC.SuppressFinalize(this); }Real-world example A wrapper around native memory uses a finalizer only as a backstop if Dispose was missed.