mscorlib(4.0.0.0) API with additions
CountdownEvent.cs
1 using System.Diagnostics;
4 
5 namespace System.Threading
6 {
8  [ComVisible(false)]
9  [DebuggerDisplay("Initial Count={InitialCount}, Current Count={CurrentCount}")]
10  [__DynamicallyInvokable]
11  [HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
12  public class CountdownEvent : IDisposable
13  {
14  private int m_initialCount;
15 
16  private volatile int m_currentCount;
17 
18  private ManualResetEventSlim m_event;
19 
20  private volatile bool m_disposed;
21 
24  [__DynamicallyInvokable]
25  public int CurrentCount
26  {
27  [__DynamicallyInvokable]
28  get
29  {
30  int currentCount = m_currentCount;
31  if (currentCount >= 0)
32  {
33  return currentCount;
34  }
35  return 0;
36  }
37  }
38 
41  [__DynamicallyInvokable]
42  public int InitialCount
43  {
44  [__DynamicallyInvokable]
45  get
46  {
47  return m_initialCount;
48  }
49  }
50 
54  [__DynamicallyInvokable]
55  public bool IsSet
56  {
57  [__DynamicallyInvokable]
58  get
59  {
60  return m_currentCount <= 0;
61  }
62  }
63 
67  [__DynamicallyInvokable]
68  public WaitHandle WaitHandle
69  {
70  [__DynamicallyInvokable]
71  get
72  {
73  ThrowIfDisposed();
74  return m_event.WaitHandle;
75  }
76  }
77 
82  [__DynamicallyInvokable]
83  public CountdownEvent(int initialCount)
84  {
85  if (initialCount < 0)
86  {
87  throw new ArgumentOutOfRangeException("initialCount");
88  }
89  m_initialCount = initialCount;
90  m_currentCount = initialCount;
91  m_event = new ManualResetEventSlim();
92  if (initialCount == 0)
93  {
94  m_event.Set();
95  }
96  }
97 
99  [__DynamicallyInvokable]
100  public void Dispose()
101  {
102  Dispose(disposing: true);
103  GC.SuppressFinalize(this);
104  }
105 
108  [__DynamicallyInvokable]
109  protected virtual void Dispose(bool disposing)
110  {
111  if (disposing)
112  {
113  m_event.Dispose();
114  m_disposed = true;
115  }
116  }
117 
122  [__DynamicallyInvokable]
123  public bool Signal()
124  {
125  ThrowIfDisposed();
126  if (m_currentCount <= 0)
127  {
128  throw new InvalidOperationException(Environment.GetResourceString("CountdownEvent_Decrement_BelowZero"));
129  }
130  int num = Interlocked.Decrement(ref m_currentCount);
131  if (num == 0)
132  {
133  m_event.Set();
134  return true;
135  }
136  if (num < 0)
137  {
138  throw new InvalidOperationException(Environment.GetResourceString("CountdownEvent_Decrement_BelowZero"));
139  }
140  return false;
141  }
142 
150  [__DynamicallyInvokable]
151  public bool Signal(int signalCount)
152  {
153  if (signalCount <= 0)
154  {
155  throw new ArgumentOutOfRangeException("signalCount");
156  }
157  ThrowIfDisposed();
158  SpinWait spinWait = default(SpinWait);
159  int currentCount;
160  while (true)
161  {
162  currentCount = m_currentCount;
163  if (currentCount < signalCount)
164  {
165  throw new InvalidOperationException(Environment.GetResourceString("CountdownEvent_Decrement_BelowZero"));
166  }
167  if (Interlocked.CompareExchange(ref m_currentCount, currentCount - signalCount, currentCount) == currentCount)
168  {
169  break;
170  }
171  spinWait.SpinOnce();
172  }
173  if (currentCount == signalCount)
174  {
175  m_event.Set();
176  return true;
177  }
178  return false;
179  }
180 
185  [__DynamicallyInvokable]
186  public void AddCount()
187  {
188  AddCount(1);
189  }
190 
196  [__DynamicallyInvokable]
197  public bool TryAddCount()
198  {
199  return TryAddCount(1);
200  }
201 
209  [__DynamicallyInvokable]
210  public void AddCount(int signalCount)
211  {
212  if (!TryAddCount(signalCount))
213  {
214  throw new InvalidOperationException(Environment.GetResourceString("CountdownEvent_Increment_AlreadyZero"));
215  }
216  }
217 
226  [__DynamicallyInvokable]
227  public bool TryAddCount(int signalCount)
228  {
229  if (signalCount <= 0)
230  {
231  throw new ArgumentOutOfRangeException("signalCount");
232  }
233  ThrowIfDisposed();
234  SpinWait spinWait = default(SpinWait);
235  while (true)
236  {
237  int currentCount = m_currentCount;
238  if (currentCount <= 0)
239  {
240  return false;
241  }
242  if (currentCount > int.MaxValue - signalCount)
243  {
244  throw new InvalidOperationException(Environment.GetResourceString("CountdownEvent_Increment_AlreadyMax"));
245  }
246  if (Interlocked.CompareExchange(ref m_currentCount, currentCount + signalCount, currentCount) == currentCount)
247  {
248  break;
249  }
250  spinWait.SpinOnce();
251  }
252  return true;
253  }
254 
257  [__DynamicallyInvokable]
258  public void Reset()
259  {
260  Reset(m_initialCount);
261  }
262 
268  [__DynamicallyInvokable]
269  public void Reset(int count)
270  {
271  ThrowIfDisposed();
272  if (count < 0)
273  {
274  throw new ArgumentOutOfRangeException("count");
275  }
276  m_currentCount = count;
277  m_initialCount = count;
278  if (count == 0)
279  {
280  m_event.Set();
281  }
282  else
283  {
284  m_event.Reset();
285  }
286  }
287 
290  [__DynamicallyInvokable]
291  public void Wait()
292  {
293  Wait(-1, default(CancellationToken));
294  }
295 
301  [__DynamicallyInvokable]
302  public void Wait(CancellationToken cancellationToken)
303  {
304  Wait(-1, cancellationToken);
305  }
306 
313  [__DynamicallyInvokable]
314  public bool Wait(TimeSpan timeout)
315  {
316  long num = (long)timeout.TotalMilliseconds;
317  if (num < -1 || num > int.MaxValue)
318  {
319  throw new ArgumentOutOfRangeException("timeout");
320  }
321  return Wait((int)num, default(CancellationToken));
322  }
323 
333  [__DynamicallyInvokable]
334  public bool Wait(TimeSpan timeout, CancellationToken cancellationToken)
335  {
336  long num = (long)timeout.TotalMilliseconds;
337  if (num < -1 || num > int.MaxValue)
338  {
339  throw new ArgumentOutOfRangeException("timeout");
340  }
341  return Wait((int)num, cancellationToken);
342  }
343 
350  [__DynamicallyInvokable]
351  public bool Wait(int millisecondsTimeout)
352  {
353  return Wait(millisecondsTimeout, default(CancellationToken));
354  }
355 
365  [__DynamicallyInvokable]
366  public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
367  {
368  if (millisecondsTimeout < -1)
369  {
370  throw new ArgumentOutOfRangeException("millisecondsTimeout");
371  }
372  ThrowIfDisposed();
373  cancellationToken.ThrowIfCancellationRequested();
374  bool flag = IsSet;
375  if (!flag)
376  {
377  flag = m_event.Wait(millisecondsTimeout, cancellationToken);
378  }
379  return flag;
380  }
381 
382  private void ThrowIfDisposed()
383  {
384  if (m_disposed)
385  {
386  throw new ObjectDisposedException("CountdownEvent");
387  }
388  }
389  }
390 }
bool Signal()
Registers a signal with the T:System.Threading.CountdownEvent, decrementing the value of P:System....
Represents a synchronization primitive that is signaled when its count reaches zero.
void Dispose()
Releases all resources used by the current instance of the T:System.Threading.ManualResetEventSlim cl...
Propagates notification that operations should be canceled.
Encapsulates operating system–specific objects that wait for exclusive access to shared resources.
Definition: WaitHandle.cs:15
void ThrowIfCancellationRequested()
Throws a T:System.OperationCanceledException if this token has had cancellation requested.
CountdownEvent(int initialCount)
Initializes a new instance of T:System.Threading.CountdownEvent class with the specified count.
static void SuppressFinalize(object obj)
Requests that the common language runtime not call the finalizer for the specified object.
Definition: GC.cs:308
Provides support for spin-based waiting.
Definition: SpinWait.cs:8
Provides a mechanism for releasing unmanaged resources.To browse the .NET Framework source code for t...
Definition: IDisposable.cs:8
Definition: __Canon.cs:3
bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
Blocks the current thread until the T:System.Threading.CountdownEvent is set, using a 32-bit signed i...
int InitialCount
Gets the numbers of signals initially required to set the event.
The exception that is thrown when the value of an argument is outside the allowable range of values a...
bool TryAddCount(int signalCount)
Attempts to increment P:System.Threading.CountdownEvent.CurrentCount by a specified value.
int CurrentCount
Gets the number of remaining signals required to set the event.
void Wait(CancellationToken cancellationToken)
Blocks the current thread until the T:System.Threading.CountdownEvent is set, while observing a T:Sys...
double TotalMilliseconds
Gets the value of the current T:System.TimeSpan structure expressed in whole and fractional milliseco...
Definition: TimeSpan.cs:180
WaitHandle WaitHandle
Gets the underlying T:System.Threading.WaitHandle object for this T:System.Threading....
void Wait()
Blocks the current thread until the current T:System.Threading.ManualResetEventSlim is set.
virtual void Dispose(bool disposing)
Releases the unmanaged resources used by the T:System.Threading.CountdownEvent, and optionally releas...
The exception that is thrown when an operation is performed on a disposed object.
SecurityAction
Specifies the security actions that can be performed using declarative security.
Provides information about, and means to manipulate, the current environment and platform....
Definition: Environment.cs:21
void Set()
Sets the state of the event to signaled, which allows one or more threads waiting on the event to pro...
void AddCount()
Increments the T:System.Threading.CountdownEvent's current count by one.
void Reset()
Resets the P:System.Threading.CountdownEvent.CurrentCount to the value of P:System....
static int CompareExchange(ref int location1, int value, int comparand)
Compares two 32-bit signed integers for equality and, if they are equal, replaces the first value.
bool IsSet
Indicates whether the T:System.Threading.CountdownEvent object's current count has reached zero....
bool Signal(int signalCount)
Registers multiple signals with the T:System.Threading.CountdownEvent, decrementing the value of P:Sy...
Provides a slimmed down version of T:System.Threading.ManualResetEvent.
bool Wait(TimeSpan timeout)
Blocks the current thread until the T:System.Threading.CountdownEvent is set, using a T:System....
void AddCount(int signalCount)
Increments the T:System.Threading.CountdownEvent's current count by a specified value.
void Reset(int count)
Resets the P:System.Threading.CountdownEvent.InitialCount property to a specified value.
Controls the system garbage collector, a service that automatically reclaims unused memory.
Definition: GC.cs:11
bool TryAddCount()
Attempts to increment P:System.Threading.CountdownEvent.CurrentCount by one.
void SpinOnce()
Performs a single spin.
Definition: SpinWait.cs:48
void Wait()
Blocks the current thread until the T:System.Threading.CountdownEvent is set.
Represents a time interval.To browse the .NET Framework source code for this type,...
Definition: TimeSpan.cs:12
The exception that is thrown when a method call is invalid for the object's current state.
void Dispose()
Releases all resources used by the current instance of the T:System.Threading.CountdownEvent class.
static int Decrement(ref int location)
Decrements a specified variable and stores the result, as an atomic operation.
Definition: Interlocked.cs:40
void Reset()
Sets the state of the event to nonsignaled, which causes threads to block.
bool Wait(int millisecondsTimeout)
Blocks the current thread until the T:System.Threading.CountdownEvent is set, using a 32-bit signed i...
Provides atomic operations for variables that are shared by multiple threads.
Definition: Interlocked.cs:10
bool Wait(TimeSpan timeout, CancellationToken cancellationToken)
Blocks the current thread until the T:System.Threading.CountdownEvent is set, using a T:System....