CountdownEvent
Represents a synchronization primitive that is signaled when its count reaches zero.
using System;
using System.Threading;
namespace Renci.SshNet.Common
{
internal class CountdownEvent : IDisposable
{
private int _count;
private ManualResetEvent _event;
private bool _disposed;
public int CurrentCount => _count;
public bool IsSet => _count == 0;
public CountdownEvent(int initialCount)
{
if (initialCount < 0)
throw new ArgumentOutOfRangeException("initialCount");
_count = initialCount;
bool initialState = _count == 0;
_event = new ManualResetEvent(initialState);
}
public bool Signal()
{
EnsureNotDisposed();
if (_count <= 0)
throw new InvalidOperationException("Invalid attempt made to decrement the event's count below zero.");
if (Interlocked.Decrement(ref _count) == 0) {
_event.Set();
return true;
}
return false;
}
public void AddCount()
{
EnsureNotDisposed();
if (_count == 2147483647)
throw new InvalidOperationException("TODO");
Interlocked.Increment(ref _count);
}
public bool Wait(TimeSpan timeout)
{
EnsureNotDisposed();
return _event.WaitOne(timeout);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing) {
ManualResetEvent event = _event;
if (event != null) {
_event = null;
event.Dispose();
}
_disposed = true;
}
}
private void EnsureNotDisposed()
{
if (_disposed)
throw new ObjectDisposedException(GetType().Name);
}
}
}