Condividi tramite


WaitHandle.WaitOne Method (Int32)

Microsoft Silverlight will reach end of support after October 2021. Learn more.

Blocks the current thread until the current WaitHandle receives a signal, using 32-bit signed integer to specify the time interval.

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

Syntax

'Declaration
Public Overridable Function WaitOne ( _
    millisecondsTimeout As Integer _
) As Boolean
public virtual bool WaitOne(
    int millisecondsTimeout
)

Parameters

Return Value

Type: System.Boolean
true if the current instance receives a signal; otherwise, false.

Exceptions

Exception Condition
ObjectDisposedException

The current instance has already been disposed.

ArgumentOutOfRangeException

millisecondsTimeout is a negative number other than -1, which represents an infinite time-out.

Remarks

If millisecondsTimeout is zero, the method does not block. It tests the state of the wait handle and returns immediately.

The caller of this method blocks until the current instance receives a signal or a time-out occurs. Use this method to block until a WaitHandle receives a signal from another thread, such as the signal that is generated when an asynchronous operation completes. For more information, see the IAsyncResult interface.

Override this method to customize the behavior of derived classes.

Examples

The following example shows how to use the WaitOne(Int32) method overload to enable the waiting thread to break out of a long wait and do some processing.

The example queues three tasks by using the ThreadPool.QueueUserWorkItem method. Each task calls WaitOne on a common AutoResetEvent, using a three-second time-out. If the wait times out, the task displays a message and resumes waiting. You could add code here to abandon the wait depending on conditions.

The example releases a waiting thread each time the MouseLeftButtonUp event occurs. When the last thread is released, it unhooks the event handler and displays a final message. The Interlocked.Increment and Interlocked.Decrement methods are used to ensure that the count is protected from concurrent access.

The example uses helper methods, executed on the user interface thread by the Dispatcher.BeginInvoke method, to safely access user interface elements from ThreadPool threads.

Imports System.Threading

' The following imports simplify the supporting code; they are not required for 
' WaitHandle:
Imports System.Windows.Controls
Imports System.Windows.Input

Public Class Example

   Private Shared outputBlock As System.Windows.Controls.TextBlock
   Private Shared autoEvent As New AutoResetEvent(False)
   Private Shared threadCount As Integer = 0

   Public Shared Sub Demo(ByVal outputBlock As System.Windows.Controls.TextBlock)

      Example.outputBlock = outputBlock

      For i As Integer = 1 To 3
         Interlocked.Increment(threadCount)
         ThreadPool.QueueUserWorkItem(AddressOf WorkMethod, i)
      Next i

      AddHandler outputBlock.MouseLeftButtonUp, AddressOf MouseUp

   End Sub

   Private Shared Sub WorkMethod(ByVal stateInfo As Object)

      Dim number As Integer = CInt(stateInfo)
      outputBlock.Dispatcher.BeginInvoke(displayHelper, _
                 String.Format("Task {0} is queued. Click to release." & vbLf, number))

      Dim start As DateTime = DateTime.Now
      While Not autoEvent.WaitOne(3000)
         outputBlock.Dispatcher.BeginInvoke(displayHelper, _
            String.Format("Task {0} has waited {1} seconds. Click to release." & vbLf, _
                          number, _
                          (DateTime.Now - start).TotalMilliseconds))
      End While

      outputBlock.Dispatcher.BeginInvoke(displayHelper, _
                 String.Format("Task {0} is ending." & vbLf, number))

      If Interlocked.Decrement(threadCount) = 0 Then

         ' Disable the mouse.
         outputBlock.Dispatcher.BeginInvoke(unhookHelper)

         outputBlock.Dispatcher.BeginInvoke(displayHelper, _
                              "Refresh the page to run the demo again." & vbLf)

      End If
   End Sub

   Private Shared Sub MouseUp(ByVal sender As Object, ByVal e As MouseButtonEventArgs)

      ' Release a thread.
      autoEvent.Set()

   End Sub

   ' Helper methods:

   ' In order to update the TextBlock object, which is on the UI thread, you must
   ' make a cross-thread call by using the Dispatcher object that is associated 
   ' with the TextBlock. The DisplayOutput helper method and its delegate, 
   ' displayHelper, are used by the BeginInvoke method of the Dispatcher object
   ' to append text to the TextBlock. UnhookMouseUp and its delegate, unhookHelper,
   ' unhook the event handler for the MouseLeftButtonUp event.
   '
   Private Shared displayHelper As New Action(Of String)(AddressOf DisplayOutput)
   Private Shared Sub DisplayOutput(ByVal msg As String)
      outputBlock.Text &= msg 
   End Sub

   Private Shared unhookHelper As New Action(AddressOf UnhookMouseUp)
   Private Shared Sub UnhookMouseUp()
      RemoveHandler outputBlock.MouseLeftButtonUp, AddressOf MouseUp
   End Sub

End Class

' This example produces output similar to the following:
'
'Task 1 is queued. Click to release.
'Task 2 is queued. Click to release.
'Task 3 is queued. Click to release.
'Task 2 has waited 3010.7421 seconds. Click to release.
'Task 1 has waited 3026.3418 seconds. Click to release.
'Task 3 has waited 3010.7421 seconds. Click to release.
'Task 3 is ending.
'Task 1 has waited 6037.0839 seconds. Click to release.
'Task 2 has waited 6021.4842 seconds. Click to release.
'Task 2 is ending.
'Task 1 is ending.
'Refresh the page to run the demo again.
using System;
using System.Threading;

// The following imports simplify the supporting code; they are not required for 
// WaitHandle:
using System.Windows.Controls;
using System.Windows.Input;

public class Example
{
   private static System.Windows.Controls.TextBlock outputBlock;
   private static AutoResetEvent autoEvent = new AutoResetEvent(false);
   private static int threadCount = 0;

   public static void Demo(TextBlock outputBlock)
   {
      Example.outputBlock = outputBlock;

      for(int i = 1; i <= 3; i++)
      {
         Interlocked.Increment(ref threadCount);
         ThreadPool.QueueUserWorkItem(WorkMethod, i);
      }

      outputBlock.MouseLeftButtonUp += MouseUp;
   }

   private static void WorkMethod(object stateInfo)
   {
      int number = (int) stateInfo;
      outputBlock.Dispatcher.BeginInvoke(displayHelper, 
            String.Format("Task {0} is queued. Click to release.\n", number));

      DateTime start = DateTime.Now;
      while (!autoEvent.WaitOne(3000))
      {
         outputBlock.Dispatcher.BeginInvoke(displayHelper, 
            String.Format("Task {0} has waited {1} seconds. Click to release.\n", 
                          number, 
                          (DateTime.Now-start).TotalMilliseconds));
      }

      outputBlock.Dispatcher.BeginInvoke(displayHelper, 
                     String.Format("Task {0} is ending.\n", number));

      if (Interlocked.Decrement(ref threadCount) == 0)
      {
         // Disable the mouse.
         outputBlock.Dispatcher.BeginInvoke(delegate () {
                                   outputBlock.MouseLeftButtonUp -= MouseUp; });

         outputBlock.Dispatcher.BeginInvoke(displayHelper, 
                         "Refresh the page to run the demo again.\n");               
      }
   }

   private static void MouseUp(object sender, MouseButtonEventArgs e)
   {
      // Release a thread.
      autoEvent.Set();
   }

   // Helper methods:

   // In order to update the TextBlock object, which is on the UI thread, you must
   // make a cross-thread call by using the Dispatcher object that is associated 
   // with the TextBlock. The DisplayOutput helper method and its delegate, 
   // displayHelper, are used by the BeginInvoke method of the Dispatcher object
   // to append text to the TextBlock. 
   //
   private static Action<string> displayHelper = new Action<string>(DisplayOutput);
   private static void DisplayOutput(string msg)
   {
      outputBlock.Text += msg;
   }
}

/* This example produces output similar to the following:

Task 1 is queued. Click to release.
Task 2 is queued. Click to release.
Task 3 is queued. Click to release.
Task 2 has waited 3010.7421 seconds. Click to release.
Task 1 has waited 3026.3418 seconds. Click to release.
Task 3 has waited 3010.7421 seconds. Click to release.
Task 3 is ending.
Task 1 has waited 6037.0839 seconds. Click to release.
Task 2 has waited 6021.4842 seconds. Click to release.
Task 2 is ending.
Task 1 is ending.
Refresh the page to run the demo again.
 */

Version Information

Silverlight

Supported in: 5, 4, 3

Silverlight for Windows Phone

Supported in: Windows Phone OS 7.1, Windows Phone OS 7.0

XNA Framework

Supported in: Xbox 360, Windows Phone OS 7.0

Platforms

For a list of the operating systems and browsers that are supported by Silverlight, see Supported Operating Systems and Browsers.