-#if NET_4_0
// CountdownEvent.cs
//
// Copyright (c) 2008 Jérémie "Garuma" Laval
//
//
+#if NET_4_0 || MOBILE
+
using System;
namespace System.Threading
-{
+{
+ [System.Diagnostics.DebuggerDisplayAttribute ("Initial Count={InitialCount}, Current Count={CurrentCount}")]
public class CountdownEvent : IDisposable
{
- int count;
- readonly int initial;
- bool isCanceled;
- ManualResetEvent evt = new ManualResetEvent (false);
+ int initialCount;
+ int initial;
+ ManualResetEventSlim evt = new ManualResetEventSlim (false);
- public CountdownEvent (int count)
+ public CountdownEvent (int initialCount)
{
- if (count < 0)
- throw new ArgumentOutOfRangeException ("count is negative");
- this.initial = this.count = count;
+ if (initialCount < 0)
+ throw new ArgumentOutOfRangeException ("initialCount is negative");
+ this.initial = this.initialCount = initialCount;
}
public bool Signal ()
return Signal (1);
}
- public bool Signal (int num)
+ public bool Signal (int signalCount)
{
- if (num < 0)
- throw new ArgumentOutOfRangeException ("num");
+ if (signalCount <= 0)
+ throw new ArgumentOutOfRangeException ("signalCount");
Action<int> check = delegate (int value) {
if (value < 0)
- throw new InvalidOperationException ("the specified count is larger that CurrentCount");
- if (IsCanceled)
- throw new OperationCanceledException ();
+ throw new InvalidOperationException ("the specified initialCount is larger that CurrentCount");
};
int newValue;
- if (!ApplyOperation (-num, check, out newValue))
+ if (!ApplyOperation (-signalCount, check, out newValue))
throw new InvalidOperationException ("The event is already set");
- if (newValue <= 0) {
+ if (newValue == 0) {
evt.Set ();
return true;
}
AddCount (1);
}
- public void AddCount (int num)
+ public void AddCount (int signalCount)
{
- if (num < 0)
- throw new ArgumentOutOfRangeException ("num");
+ if (signalCount < 0)
+ throw new ArgumentOutOfRangeException ("signalCount");
- if (!TryAddCount (num))
+ if (!TryAddCount (signalCount))
throw new InvalidOperationException ("The event is already set");
}
return TryAddCount (1);
}
- public bool TryAddCount (int num)
+ public bool TryAddCount (int signalCount)
{
- if (num < 0)
- throw new ArgumentOutOfRangeException ("num");
-
- Action<int> check = delegate (int value) {
- if (IsCanceled)
- throw new OperationCanceledException ();
- };
+ if (signalCount < 0)
+ throw new ArgumentOutOfRangeException ("signalCount");
- return ApplyOperation (num, check);
+ return ApplyOperation (signalCount, null);
}
bool ApplyOperation (int num, Action<int> doCheck)
newValue = 0;
do {
- if (IsSet)
+ oldCount = initialCount;
+ if (oldCount == 0)
return false;
- oldCount = count;
newValue = oldCount + num;
- doCheck (newValue);
-
- } while (Interlocked.CompareExchange (ref count, newValue, oldCount) != oldCount);
+ if (doCheck != null)
+ doCheck (newValue);
+ } while (Interlocked.CompareExchange (ref initialCount, newValue, oldCount) != oldCount);
return true;
}
public void Wait ()
{
- SpinWait wait = new SpinWait ();
- while (!IsSet) {
- wait.SpinOnce ();
- }
+ evt.Wait ();
}
- public bool Wait (int timeoutMilli)
+ public void Wait (CancellationToken cancellationToken)
{
- if (timeoutMilli == -1) {
- Wait ();
- return true;
- }
-
- Watch sw = Watch.StartNew ();
- long timeout = (long)timeoutMilli;
-
- bool result = Wait (() => sw.ElapsedMilliseconds > timeout);
- sw.Stop ();
-
- return result;
+ evt.Wait (cancellationToken);
}
- public bool Wait(TimeSpan span)
+ public bool Wait (int millisecondsTimeout)
{
- return Wait ((int)span.TotalMilliseconds);
+ return evt.Wait (millisecondsTimeout);
}
- public bool Wait (int timeoutMilli, CancellationToken token)
+ public bool Wait(TimeSpan timeout)
{
- if (timeoutMilli == -1) {
- Wait ();
- return true;
- }
-
- Watch sw = Watch.StartNew ();
- long timeout = (long)timeoutMilli;
-
- bool result = Wait (() => sw.ElapsedMilliseconds > timeout || token.IsCancellationRequested);
- sw.Stop ();
-
- return result;
+ return evt.Wait (timeout);
}
- public bool Wait(TimeSpan span, CancellationToken token)
+ public bool Wait (int millisecondsTimeout, CancellationToken cancellationToken)
{
- return Wait ((int)span.TotalMilliseconds, token);
+ return evt.Wait (millisecondsTimeout, cancellationToken);
}
- bool Wait (Func<bool> waitPredicate)
+ public bool Wait(TimeSpan timeout, CancellationToken cancellationToken)
{
- SpinWait wait = new SpinWait ();
-
- while (!IsSet) {
- if (waitPredicate ())
- return false;
- wait.SpinOnce ();
- }
-
- return true;
+ return evt.Wait (timeout, cancellationToken);
}
-
+
public void Reset ()
{
Reset (initial);
}
- public void Reset (int value)
+ public void Reset (int count)
{
evt.Reset ();
- Interlocked.Exchange (ref count, value);
+ initialCount = initial = count;
}
public int CurrentCount {
get {
- return count;
+ return initialCount;
}
}
public bool IsSet {
get {
- return count <= 0;
+ return initialCount == 0;
}
}
public WaitHandle WaitHandle {
get {
- return evt;
+ return evt.WaitHandle;
}
}
{
}
- #endregion
-
- #region ISupportsCancellation implementation
-
- public void Cancel ()
+ protected virtual void Dispose (bool disposing)
{
- Interlocked.Exchange (ref count, 0);
- isCanceled = true;
- }
-
- public bool IsCanceled {
- get {
- return isCanceled;
- }
+
}
-
- #endregion
-
+ #endregion
}
}
#endif