mscorlib(4.0.0.0) API with additions
WaitHandle.cs
1 using Microsoft.Win32;
2 using Microsoft.Win32.SafeHandles;
7 using System.Security;
9 
10 namespace System.Threading
11 {
13  [ComVisible(true)]
14  [__DynamicallyInvokable]
15  public abstract class WaitHandle : MarshalByRefObject, IDisposable
16  {
17  internal enum OpenExistingResult
18  {
19  Success,
20  NameNotFound,
21  PathNotFound,
22  NameInvalid
23  }
24 
26  [__DynamicallyInvokable]
27  public const int WaitTimeout = 258;
28 
29  private const int MAX_WAITHANDLES = 64;
30 
31  private IntPtr waitHandle;
32 
33  [SecurityCritical]
34  internal volatile SafeWaitHandle safeWaitHandle;
35 
36  internal bool hasThreadAffinity;
37 
39  protected static readonly IntPtr InvalidHandle = GetInvalidHandle();
40 
41  private const int WAIT_OBJECT_0 = 0;
42 
43  private const int WAIT_ABANDONED = 128;
44 
45  private const int WAIT_FAILED = int.MaxValue;
46 
47  private const int ERROR_TOO_MANY_POSTS = 298;
48 
51  [Obsolete("Use the SafeWaitHandle property instead.")]
52  public virtual IntPtr Handle
53  {
54  [SecuritySafeCritical]
55  get
56  {
57  if (safeWaitHandle != null)
58  {
59  return safeWaitHandle.DangerousGetHandle();
60  }
61  return InvalidHandle;
62  }
63  [SecurityCritical]
64  [SecurityPermission(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
65  set
66  {
67  if (value == InvalidHandle)
68  {
69  if (safeWaitHandle != null)
70  {
71  safeWaitHandle.SetHandleAsInvalid();
72  safeWaitHandle = null;
73  }
74  }
75  else
76  {
77  safeWaitHandle = new SafeWaitHandle(value, ownsHandle: true);
78  }
79  waitHandle = value;
80  }
81  }
82 
86  {
87  [SecurityCritical]
88  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
89  [SecurityPermission(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
90  get
91  {
92  if (safeWaitHandle == null)
93  {
94  safeWaitHandle = new SafeWaitHandle(InvalidHandle, ownsHandle: false);
95  }
96  return safeWaitHandle;
97  }
98  [SecurityCritical]
99  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
100  [SecurityPermission(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
101  set
102  {
104  try
105  {
106  }
107  finally
108  {
109  if (value == null)
110  {
111  safeWaitHandle = null;
112  waitHandle = InvalidHandle;
113  }
114  else
115  {
116  safeWaitHandle = value;
117  waitHandle = safeWaitHandle.DangerousGetHandle();
118  }
119  }
120  }
121  }
122 
123  [SecuritySafeCritical]
124  private static IntPtr GetInvalidHandle()
125  {
126  return Win32Native.INVALID_HANDLE_VALUE;
127  }
128 
130  [__DynamicallyInvokable]
131  protected WaitHandle()
132  {
133  Init();
134  }
135 
136  [SecuritySafeCritical]
137  private void Init()
138  {
139  safeWaitHandle = null;
140  waitHandle = InvalidHandle;
141  hasThreadAffinity = false;
142  }
143 
144  [SecurityCritical]
145  internal void SetHandleInternal(SafeWaitHandle handle)
146  {
147  safeWaitHandle = handle;
148  waitHandle = handle.DangerousGetHandle();
149  }
150 
162  public virtual bool WaitOne(int millisecondsTimeout, bool exitContext)
163  {
164  if (millisecondsTimeout < -1)
165  {
166  throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
167  }
168  return WaitOne((long)millisecondsTimeout, exitContext);
169  }
170 
184  public virtual bool WaitOne(TimeSpan timeout, bool exitContext)
185  {
186  long num = (long)timeout.TotalMilliseconds;
187  if (-1 > num || int.MaxValue < num)
188  {
189  throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
190  }
191  return WaitOne(num, exitContext);
192  }
193 
200  [__DynamicallyInvokable]
201  public virtual bool WaitOne()
202  {
203  return WaitOne(-1, exitContext: false);
204  }
205 
215  [__DynamicallyInvokable]
216  public virtual bool WaitOne(int millisecondsTimeout)
217  {
218  return WaitOne(millisecondsTimeout, exitContext: false);
219  }
220 
231  [__DynamicallyInvokable]
232  public virtual bool WaitOne(TimeSpan timeout)
233  {
234  return WaitOne(timeout, exitContext: false);
235  }
236 
237  [SecuritySafeCritical]
238  private bool WaitOne(long timeout, bool exitContext)
239  {
240  return InternalWaitOne(safeWaitHandle, timeout, hasThreadAffinity, exitContext);
241  }
242 
243  [SecurityCritical]
244  internal static bool InternalWaitOne(SafeHandle waitableSafeHandle, long millisecondsTimeout, bool hasThreadAffinity, bool exitContext)
245  {
246  if (waitableSafeHandle == null)
247  {
248  throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_Generic"));
249  }
250  int num = WaitOneNative(waitableSafeHandle, (uint)millisecondsTimeout, hasThreadAffinity, exitContext);
251  if (AppDomainPauseManager.IsPaused)
252  {
253  AppDomainPauseManager.ResumeEvent.WaitOneWithoutFAS();
254  }
255  if (num == 128)
256  {
257  ThrowAbandonedMutexException();
258  }
259  return num != 258;
260  }
261 
262  [SecurityCritical]
263  internal bool WaitOneWithoutFAS()
264  {
265  if (safeWaitHandle == null)
266  {
267  throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_Generic"));
268  }
269  long num = -1L;
270  int num2 = WaitOneNative(safeWaitHandle, (uint)num, hasThreadAffinity, exitContext: false);
271  if (num2 == 128)
272  {
273  ThrowAbandonedMutexException();
274  }
275  return num2 != 258;
276  }
277 
278  [MethodImpl(MethodImplOptions.InternalCall)]
279  [SecurityCritical]
280  private static extern int WaitOneNative(SafeHandle waitableSafeHandle, uint millisecondsTimeout, bool hasThreadAffinity, bool exitContext);
281 
282  [MethodImpl(MethodImplOptions.InternalCall)]
283  [SecurityCritical]
284  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
285  private static extern int WaitMultiple(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext, bool WaitAll);
286 
304  [SecuritySafeCritical]
305  public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
306  {
307  if (waitHandles == null)
308  {
309  throw new ArgumentNullException(Environment.GetResourceString("ArgumentNull_Waithandles"));
310  }
311  if (waitHandles.Length == 0)
312  {
313  throw new ArgumentNullException(Environment.GetResourceString("Argument_EmptyWaithandleArray"));
314  }
315  if (waitHandles.Length > 64)
316  {
317  throw new NotSupportedException(Environment.GetResourceString("NotSupported_MaxWaitHandles"));
318  }
319  if (-1 > millisecondsTimeout)
320  {
321  throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
322  }
323  WaitHandle[] array = new WaitHandle[waitHandles.Length];
324  for (int i = 0; i < waitHandles.Length; i++)
325  {
326  WaitHandle waitHandle = waitHandles[i];
327  if (waitHandle == null)
328  {
329  throw new ArgumentNullException(Environment.GetResourceString("ArgumentNull_ArrayElement"));
330  }
331  if (RemotingServices.IsTransparentProxy(waitHandle))
332  {
333  throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WaitOnTransparentProxy"));
334  }
335  array[i] = waitHandle;
336  }
337  int num = WaitMultiple(array, millisecondsTimeout, exitContext, WaitAll: true);
338  if (AppDomainPauseManager.IsPaused)
339  {
340  AppDomainPauseManager.ResumeEvent.WaitOneWithoutFAS();
341  }
342  if (128 <= num && 128 + array.Length > num)
343  {
344  ThrowAbandonedMutexException();
345  }
346  GC.KeepAlive(array);
347  return num != 258;
348  }
349 
369  public static bool WaitAll(WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext)
370  {
371  long num = (long)timeout.TotalMilliseconds;
372  if (-1 > num || int.MaxValue < num)
373  {
374  throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
375  }
376  return WaitAll(waitHandles, (int)num, exitContext);
377  }
378 
392  [__DynamicallyInvokable]
393  public static bool WaitAll(WaitHandle[] waitHandles)
394  {
395  return WaitAll(waitHandles, -1, exitContext: true);
396  }
397 
412  [__DynamicallyInvokable]
413  public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout)
414  {
415  return WaitAll(waitHandles, millisecondsTimeout, exitContext: true);
416  }
417 
433  [__DynamicallyInvokable]
434  public static bool WaitAll(WaitHandle[] waitHandles, TimeSpan timeout)
435  {
436  return WaitAll(waitHandles, timeout, exitContext: true);
437  }
438 
455  [SecuritySafeCritical]
456  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
457  public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
458  {
459  if (waitHandles == null)
460  {
461  throw new ArgumentNullException(Environment.GetResourceString("ArgumentNull_Waithandles"));
462  }
463  if (waitHandles.Length == 0)
464  {
465  throw new ArgumentException(Environment.GetResourceString("Argument_EmptyWaithandleArray"));
466  }
467  if (64 < waitHandles.Length)
468  {
469  throw new NotSupportedException(Environment.GetResourceString("NotSupported_MaxWaitHandles"));
470  }
471  if (-1 > millisecondsTimeout)
472  {
473  throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
474  }
475  WaitHandle[] array = new WaitHandle[waitHandles.Length];
476  for (int i = 0; i < waitHandles.Length; i++)
477  {
478  WaitHandle waitHandle = waitHandles[i];
479  if (waitHandle == null)
480  {
481  throw new ArgumentNullException(Environment.GetResourceString("ArgumentNull_ArrayElement"));
482  }
483  if (RemotingServices.IsTransparentProxy(waitHandle))
484  {
485  throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WaitOnTransparentProxy"));
486  }
487  array[i] = waitHandle;
488  }
489  int num = WaitMultiple(array, millisecondsTimeout, exitContext, WaitAll: false);
490  if (AppDomainPauseManager.IsPaused)
491  {
492  AppDomainPauseManager.ResumeEvent.WaitOneWithoutFAS();
493  }
494  if (128 <= num && 128 + array.Length > num)
495  {
496  int num2 = num - 128;
497  if (0 <= num2 && num2 < array.Length)
498  {
499  ThrowAbandonedMutexException(num2, array[num2]);
500  }
501  else
502  {
503  ThrowAbandonedMutexException();
504  }
505  }
506  GC.KeepAlive(array);
507  return num;
508  }
509 
528  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
529  public static int WaitAny(WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext)
530  {
531  long num = (long)timeout.TotalMilliseconds;
532  if (-1 > num || int.MaxValue < num)
533  {
534  throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
535  }
536  return WaitAny(waitHandles, (int)num, exitContext);
537  }
538 
552  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
553  [__DynamicallyInvokable]
554  public static int WaitAny(WaitHandle[] waitHandles, TimeSpan timeout)
555  {
556  return WaitAny(waitHandles, timeout, exitContext: true);
557  }
558 
570  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
571  [__DynamicallyInvokable]
572  public static int WaitAny(WaitHandle[] waitHandles)
573  {
574  return WaitAny(waitHandles, -1, exitContext: true);
575  }
576 
589  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
590  [__DynamicallyInvokable]
591  public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout)
592  {
593  return WaitAny(waitHandles, millisecondsTimeout, exitContext: true);
594  }
595 
596  [MethodImpl(MethodImplOptions.InternalCall)]
597  [SecurityCritical]
598  private static extern int SignalAndWaitOne(SafeWaitHandle waitHandleToSignal, SafeWaitHandle waitHandleToWaitOn, int millisecondsTimeout, bool hasThreadAffinity, bool exitContext);
599 
613  public static bool SignalAndWait(WaitHandle toSignal, WaitHandle toWaitOn)
614  {
615  return SignalAndWait(toSignal, toWaitOn, -1, exitContext: false);
616  }
617 
638  public static bool SignalAndWait(WaitHandle toSignal, WaitHandle toWaitOn, TimeSpan timeout, bool exitContext)
639  {
640  long num = (long)timeout.TotalMilliseconds;
641  if (-1 > num || int.MaxValue < num)
642  {
643  throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
644  }
645  return SignalAndWait(toSignal, toWaitOn, (int)num, exitContext);
646  }
647 
667  [SecuritySafeCritical]
668  public static bool SignalAndWait(WaitHandle toSignal, WaitHandle toWaitOn, int millisecondsTimeout, bool exitContext)
669  {
670  if (toSignal == null)
671  {
672  throw new ArgumentNullException("toSignal");
673  }
674  if (toWaitOn == null)
675  {
676  throw new ArgumentNullException("toWaitOn");
677  }
678  if (-1 > millisecondsTimeout)
679  {
680  throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
681  }
682  int num = SignalAndWaitOne(toSignal.safeWaitHandle, toWaitOn.safeWaitHandle, millisecondsTimeout, toWaitOn.hasThreadAffinity, exitContext);
683  if (int.MaxValue != num && toSignal.hasThreadAffinity)
684  {
687  }
688  if (128 == num)
689  {
690  ThrowAbandonedMutexException();
691  }
692  if (298 == num)
693  {
694  throw new InvalidOperationException(Environment.GetResourceString("Threading.WaitHandleTooManyPosts"));
695  }
696  if (num == 0)
697  {
698  return true;
699  }
700  return false;
701  }
702 
703  private static void ThrowAbandonedMutexException()
704  {
705  throw new AbandonedMutexException();
706  }
707 
708  private static void ThrowAbandonedMutexException(int location, WaitHandle handle)
709  {
710  throw new AbandonedMutexException(location, handle);
711  }
712 
714  public virtual void Close()
715  {
716  Dispose(explicitDisposing: true);
717  GC.SuppressFinalize(this);
718  }
719 
723  [SecuritySafeCritical]
724  [__DynamicallyInvokable]
725  protected virtual void Dispose(bool explicitDisposing)
726  {
727  if (safeWaitHandle != null)
728  {
729  safeWaitHandle.Close();
730  }
731  }
732 
734  [__DynamicallyInvokable]
735  public void Dispose()
736  {
737  Dispose(explicitDisposing: true);
738  GC.SuppressFinalize(this);
739  }
740  }
741 }
void Dispose()
Releases all resources used by the current instance of the T:System.Threading.WaitHandle class.
Definition: WaitHandle.cs:735
virtual bool WaitOne(TimeSpan timeout, bool exitContext)
Blocks the current thread until the current instance receives a signal, using a T:System....
Definition: WaitHandle.cs:184
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
Describes a set of security permissions applied to code. This class cannot be inherited.
static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout)
Waits for all the elements in the specified array to receive a signal, using an T:System....
Definition: WaitHandle.cs:413
static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
Waits for any of the elements in the specified array to receive a signal, using a 32-bit signed integ...
Definition: WaitHandle.cs:457
static bool SignalAndWait(WaitHandle toSignal, WaitHandle toWaitOn, TimeSpan timeout, bool exitContext)
Signals one T:System.Threading.WaitHandle and waits on another, specifying the time-out interval as a...
Definition: WaitHandle.cs:638
Encapsulates operating system–specific objects that wait for exclusive access to shared resources.
Definition: WaitHandle.cs:15
SafeWaitHandle SafeWaitHandle
Gets or sets the native operating system handle.
Definition: WaitHandle.cs:86
static void SuppressFinalize(object obj)
Requests that the common language runtime not call the finalizer for the specified object.
Definition: GC.cs:308
static bool SignalAndWait(WaitHandle toSignal, WaitHandle toWaitOn, int millisecondsTimeout, bool exitContext)
Signals one T:System.Threading.WaitHandle and waits on another, specifying a time-out interval as a 3...
Definition: WaitHandle.cs:668
static bool WaitAll(WaitHandle[] waitHandles)
Waits for all the elements in the specified array to receive a signal.
Definition: WaitHandle.cs:393
static bool WaitAll(WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext)
Waits for all the elements in the specified array to receive a signal, using a T:System....
Definition: WaitHandle.cs:369
Provides a mechanism for releasing unmanaged resources.To browse the .NET Framework source code for t...
Definition: IDisposable.cs:8
Definition: __Canon.cs:3
static bool WaitAll(WaitHandle[] waitHandles, TimeSpan timeout)
Waits for all the elements in the specified array to receive a signal, using a T:System....
Definition: WaitHandle.cs:434
The exception that is thrown when the value of an argument is outside the allowable range of values a...
static void KeepAlive(object obj)
References the specified object, which makes it ineligible for garbage collection from the start of t...
Definition: GC.cs:267
static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout)
Waits for any of the elements in the specified array to receive a signal, using a 32-bit signed integ...
Definition: WaitHandle.cs:591
virtual IntPtr Handle
Gets or sets the native operating system handle.
Definition: WaitHandle.cs:53
double TotalMilliseconds
Gets the value of the current T:System.TimeSpan structure expressed in whole and fractional milliseco...
Definition: TimeSpan.cs:180
virtual bool WaitOne(int millisecondsTimeout, bool exitContext)
Blocks the current thread until the current T:System.Threading.WaitHandle receives a signal,...
Definition: WaitHandle.cs:162
Represents a wrapper class for operating system handles. This class must be inherited.
Definition: SafeHandle.cs:12
Cer
Specifies a method's behavior when called within a constrained execution region.
Definition: Cer.cs:5
The exception that is thrown when an operation is performed on a disposed object.
virtual bool WaitOne(int millisecondsTimeout)
Blocks the current thread until the current T:System.Threading.WaitHandle receives a signal,...
Definition: WaitHandle.cs:216
SecurityAction
Specifies the security actions that can be performed using declarative security.
static int WaitAny(WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext)
Waits for any of the elements in the specified array to receive a signal, using a T:System....
Definition: WaitHandle.cs:529
Provides information about, and means to manipulate, the current environment and platform....
Definition: Environment.cs:21
static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
Waits for all the elements in the specified array to receive a signal, using an T:System....
Definition: WaitHandle.cs:305
static bool SignalAndWait(WaitHandle toSignal, WaitHandle toWaitOn)
Signals one T:System.Threading.WaitHandle and waits on another.
Definition: WaitHandle.cs:613
static readonly IntPtr InvalidHandle
Represents an invalid native operating system handle. This field is read-only.
Definition: WaitHandle.cs:39
virtual void Dispose(bool explicitDisposing)
When overridden in a derived class, releases the unmanaged resources used by the T:System....
Definition: WaitHandle.cs:725
A platform-specific type that is used to represent a pointer or a handle.
Definition: IntPtr.cs:14
static int WaitAny(WaitHandle[] waitHandles)
Waits for any of the elements in the specified array to receive a signal.
Definition: WaitHandle.cs:572
static void PrepareConstrainedRegions()
Designates a body of code as a constrained execution region (CER).
The exception that is thrown when one thread acquires a T:System.Threading.Mutex object that another ...
MethodImplOptions
Defines the details of how a method is implemented.
static void EndCriticalRegion()
Notifies a host that execution is about to enter a region of code in which the effects of a thread ab...
virtual void Close()
Releases all resources held by the current T:System.Threading.WaitHandle.
Definition: WaitHandle.cs:714
static int WaitAny(WaitHandle[] waitHandles, TimeSpan timeout)
Waits for any of the elements in the specified array to receive a signal, using a T:System....
Definition: WaitHandle.cs:554
Controls the system garbage collector, a service that automatically reclaims unused memory.
Definition: GC.cs:11
static bool IsTransparentProxy(object proxy)
Returns a Boolean value that indicates whether the given object is a transparent proxy or a real obje...
virtual bool WaitOne(TimeSpan timeout)
Blocks the current thread until the current instance receives a signal, using a T:System....
Definition: WaitHandle.cs:232
virtual bool WaitOne()
Blocks the current thread until the current T:System.Threading.WaitHandle receives a signal.
Definition: WaitHandle.cs:201
The exception that is thrown when one of the arguments provided to a method is not valid.
WaitHandle()
Initializes a new instance of the T:System.Threading.WaitHandle class.
Definition: WaitHandle.cs:131
Represents a time interval.To browse the .NET Framework source code for this type,...
Definition: TimeSpan.cs:12
static void EndThreadAffinity()
Notifies a host that managed code has finished executing instructions that depend on the identity of ...
The exception that is thrown when a method call is invalid for the object's current state.
Consistency
Specifies a reliability contract.
Definition: Consistency.cs:5
The exception that is thrown when an invoked method is not supported, or when there is an attempt to ...
SecurityPermissionFlag
Specifies access flags for the security permission object.
Provides several methods for using and publishing remoted objects and proxies. This class cannot be i...
const int WaitTimeout
Indicates that a M:System.Threading.WaitHandle.WaitAny(System.Threading.WaitHandle[],...
Definition: WaitHandle.cs:27
Provides a set of static methods and properties that provide support for compilers....
Enables access to objects across application domain boundaries in applications that support remoting.
Creates and controls a thread, sets its priority, and gets its status.
Definition: Thread.cs:18