get
{
// The latch is "completed" if its current count has reached 0. Note that this is NOT
- // the same thing is checking the event's IsCompleted property. There is a tiny window
+ // the same thing is checking the event's IsSet property. There is a tiny window
// of time, after the final decrement of the current count to 0 and before setting the
// event, where the two values are out of sync.
return (_currentCount <= 0);
ThrowIfDisposed();
cancellationToken.ThrowIfCancellationRequested();
- bool returnValue = IsSet;
+ // Check whether the event is already set. This is checked instead of this.IsSet, as this.Signal
+ // will first decrement the count and then if it's 0 will set the event, thus it's possible
+ // we could observe this.IsSet as true while _event.IsSet is false; that could in turn lead
+ // a caller to think it's safe to use Reset, while an operation is still in flight calling _event.Set.
+ bool returnValue = _event.IsSet;
// If not completed yet, wait on the event.
if (!returnValue)