The managed ThreadPool provides a way to asynchronously wait for WaitHandles, via ThreadPool.RegisterWaitForSingleObject. This method returns a new instance of RegisteredWaitHandle, which has a single method: Unregister. It’s obvious from the name that this will cancel a pending wait operation. What’s not obvious is that even after a registered wait has completed, you should still call Unregister.
The reason is that RegisteredWaitHandle holds a reference to your WaitHandle, and holds a refcount on the underlying SafeHandle. If you don’t call Unregister, then RegisteredWaitHandle will have to run its finalizer sometime later, before it can release the WaitHandle. Calling Unregister prevents the finalizer from running (which helps perf), and may get your handle closed faster.
RegisteredWaitHandle really, really should implement IDisposable.