Export (0) Print
Expand All

ThreadPool.RegisterWaitForSingleObject Method (WaitHandle, WaitOrTimerCallback, Object, UInt32, Boolean)

Registers a delegate to wait for a WaitHandle, specifying a 32-bit unsigned integer for the time-out in milliseconds.

This API is not CLS-compliant. 

Namespace:  System.Threading
Assembly:  mscorlib (in mscorlib.dll)

'Declaration
<CLSCompliantAttribute(False)> _
Public Shared Function RegisterWaitForSingleObject ( _
	waitObject As WaitHandle, _
	callBack As WaitOrTimerCallback, _
	state As Object, _
	millisecondsTimeOutInterval As UInteger, _
	executeOnlyOnce As Boolean _
) As RegisteredWaitHandle

Parameters

waitObject
Type: System.Threading.WaitHandle

The WaitHandle to register. Use a WaitHandle other than Mutex.

callBack
Type: System.Threading.WaitOrTimerCallback

The WaitOrTimerCallback delegate to call when the waitObject parameter is signaled.

state
Type: System.Object

The object passed to the delegate.

millisecondsTimeOutInterval
Type: System.UInt32

The time-out in milliseconds. If the millisecondsTimeOutInterval parameter is 0 (zero), the function tests the object's state and returns immediately. If millisecondsTimeOutInterval is -1, the function's time-out interval never elapses.

executeOnlyOnce
Type: System.Boolean

true to indicate that the thread will no longer wait on the waitObject parameter after the delegate has been called; false to indicate that the timer is reset every time the wait operation completes until the wait is unregistered.

Return Value

Type: System.Threading.RegisteredWaitHandle
The RegisteredWaitHandle that can be used to cancel the registered wait operation.

ExceptionCondition
ArgumentOutOfRangeException

The millisecondsTimeOutInterval parameter is less than -1.

When you are finished using the RegisteredWaitHandle that is returned by this method, call its RegisteredWaitHandle.Unregister method to release references to the wait handle. We recommend that you always call the RegisteredWaitHandle.Unregister method, even if you specify true for executeOnlyOnce. Garbage collection works more efficiently if you call the RegisteredWaitHandle.Unregister method instead of depending on the registered wait handle's finalizer.

The RegisterWaitForSingleObject method queues the specified delegate to the thread pool. A worker thread will execute the delegate when one of the following occurs:

  • The specified object is in the signaled state.

  • The time-out interval elapses.

The RegisterWaitForSingleObjectmethod checks the current state of the specified object's WaitHandle. If the object's state is unsignaled, the method registers a wait operation. The wait operation is performed by a thread from the thread pool. The delegate is executed by a worker thread when the object's state becomes signaled or the time-out interval elapses. If the timeOutInterval parameter is not 0 (zero) and the executeOnlyOnce parameter is false, the timer is reset every time the event is signaled or the time-out interval elapses.

Important noteImportant

Using a Mutex for waitObject does not provide mutual exclusion for the callbacks because the underlying Win32 API uses the default WT_EXECUTEDEFAULT flag, so each callback is dispatched on a separate thread pool thread. Instead of a Mutex, use a Semaphore with a maximum count of 1.

To cancel the wait operation, call the RegisteredWaitHandle.Unregister method.

The wait thread uses the Win32 WaitForMultipleObjects function to monitor registered wait operations. Therefore, if you must use the same native operating system handle in multiple calls to RegisterWaitForSingleObject, you must duplicate the handle using the Win32 DuplicateHandle function. Note that you should not pulse an event object passed to RegisterWaitForSingleObject, because the wait thread might not detect that the event is signaled before it is reset.

Before returning, the function modifies the state of some types of synchronization objects. Modification occurs only for the object whose signaled state caused the wait condition to be satisfied. For example, the count of a semaphore is decreased by one.

Version Information

Starting with the .NET Framework version 2.0, the Thread.CurrentPrincipal property value is propagated to worker threads queued using the RegisterWaitForSingleObject method. In earlier versions, the principal information is not propagated.

The following example shows how to use the RegisterWaitForSingleObject method to execute a specified callback method when a specified wait handle is signaled. In this example, the callback method is WaitProc, and the wait handle is an AutoResetEvent.

The example defines a TaskInfo class to hold the information that is passed to the callback when it executes. The example creates a TaskInfo object and assigns it some string data. The RegisteredWaitHandle that is returned by the RegisterWaitForSingleObject method is assigned to the Handle field of the TaskInfo object so that the callback method has access to the RegisteredWaitHandle.

In addition to specifying TaskInfo as the object to pass to the callback method, the call to the RegisterWaitForSingleObject method specifies the AutoResetEvent that the task will wait for, a WaitOrTimerCallback delegate that represents the WaitProc callback method, a one second time-out interval, and multiple callbacks.

When the main thread signals the AutoResetEvent by calling its Set method, the WaitOrTimerCallback delegate is invoked. The WaitProc method tests RegisteredWaitHandle to determine whether a time-out occurred. If the callback was invoked because the wait handle was signaled, the WaitProc method unregisters the RegisteredWaitHandle, stopping additional callbacks. In the case of a time-out, the task continues to wait. The WaitProc method ends by printing a message to the console.

Imports System
Imports System.Threading

' TaskInfo contains data that will be passed to the callback 
' method. 
Public Class TaskInfo
    public Handle As RegisteredWaitHandle = Nothing
    public OtherInfo As String = "default" 
End Class 

Public Class Example

    <MTAThread> _
    Public Shared Sub Main()
        ' The main thread uses AutoResetEvent to signal the 
        ' registered wait handle, which executes the callback 
        ' method. 
        Dim ev As New AutoResetEvent(false)

        Dim ti As New TaskInfo()
        ti.OtherInfo = "First task" 
        ' The TaskInfo for the task includes the registered wait 
        ' handle returned by RegisterWaitForSingleObject.  This 
        ' allows the wait to be terminated when the object has 
        ' been signaled once (see WaitProc).
        ti.Handle = ThreadPool.RegisterWaitForSingleObject( _
            ev, _
            New WaitOrTimerCallback(AddressOf WaitProc), _
            ti, _
            1000, _
            false _
        )

        ' The main thread waits about three seconds, to demonstrate  
        ' the time-outs on the queued task, and then signals.
        Thread.Sleep(3100)
        Console.WriteLine("Main thread signals.")
        ev.Set()

        ' The main thread sleeps, which should give the callback 
        ' method time to execute.  If you comment out this line, the 
        ' program usually ends before the ThreadPool thread can execute.
        Thread.Sleep(1000)
        ' If you start a thread yourself, you can wait for it to end 
        ' by calling Thread.Join.  This option is not available with  
        ' thread pool threads. 
    End Sub 

    ' The callback method executes when the registered wait times out, 
    ' or when the WaitHandle (in this case AutoResetEvent) is signaled. 
    ' WaitProc unregisters the WaitHandle the first time the event is  
    ' signaled. 
    Public Shared Sub WaitProc(state As Object, timedOut As Boolean)
        ' The state object must be cast to the correct type, because the 
        ' signature of the WaitOrTimerCallback delegate specifies type 
        ' Object. 
        Dim ti As TaskInfo = CType(state, TaskInfo)

        Dim cause As String = "TIMED OUT" 
        If Not timedOut Then
            cause = "SIGNALED" 
            ' If the callback method executes because the WaitHandle is 
            ' signaled, stop future execution of the callback method 
            ' by unregistering the WaitHandle. 
            If Not ti.Handle Is Nothing Then
                ti.Handle.Unregister(Nothing)
            End If 
        End If 

        Console.WriteLine("WaitProc( {0} ) executes on thread {1}; cause = {2}.", _
            ti.OtherInfo, _
            Thread.CurrentThread.GetHashCode().ToString(), _
            cause _
        )
    End Sub 
End Class

.NET Framework

Supported in: 4.6, 4.5, 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework Client Profile

Supported in: 4, 3.5 SP1

Supported in: Windows Phone 8.1

Supported in: Windows Phone Silverlight 8.1

Supported in: Windows Phone Silverlight 8

Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (Server Core Role not supported), Windows Server 2008 R2 (Server Core Role supported with SP1 or later; Itanium not supported)

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

Show:
© 2014 Microsoft