Comparteix a través de


WaitHandle.WaitOne Método

Definición

Bloquea el subproceso actual hasta que el objeto WaitHandle actual recibe una señal.

Sobrecargas

WaitOne()

Bloquea el subproceso actual hasta que el objeto WaitHandle actual recibe una señal.

WaitOne(Int32)

Bloquea el subproceso actual hasta que el objeto WaitHandle actual recibe una señal, usando un entero de 32 bits con signo para especificar el intervalo de tiempo en milisegundos.

WaitOne(TimeSpan)

Bloquea el subproceso actual hasta que la instancia actual recibe una señal, usando TimeSpan para especificar el intervalo de tiempo.

WaitOne(Int32, Boolean)

Bloquea el subproceso actual hasta que el objeto WaitHandle actual recibe una señal, usa un entero de 32 bits con signo para determinar el intervalo de tiempo y especifica si hay que salir del dominio de sincronización antes de la espera.

WaitOne(TimeSpan, Boolean)

Bloquea el subproceso actual hasta que la instancia actual recibe una señal; usa TimeSpan para determinar el intervalo de tiempo y especifica si hay que abandonar el dominio de sincronización antes de la espera.

WaitOne()

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

Bloquea el subproceso actual hasta que el objeto WaitHandle actual recibe una señal.

public:
 virtual bool WaitOne();
public virtual bool WaitOne ();
abstract member WaitOne : unit -> bool
override this.WaitOne : unit -> bool
Public Overridable Function WaitOne () As Boolean

Devoluciones

Es true si la instancia actual recibe una señal. Si nunca se señala a la instancia actual, WaitOne() nunca devuelve nada.

Excepciones

Ya se ha eliminado la instancia actual.

La espera finalizó porque un subproceso se cierra sin liberar una exclusión mutua.

La instancia actual es un proxy transparente para un objeto WaitHandle en otro dominio de aplicación.

Ejemplos

En el ejemplo de código siguiente se muestra cómo usar un identificador de espera para evitar que un proceso finalice mientras espera a que un subproceso en segundo plano termine de ejecutarse.

using namespace System;
using namespace System::Threading;
ref class WaitOne
{
private:
   WaitOne(){}


public:
   static void WorkMethod( Object^ stateInfo )
   {
      Console::WriteLine( "Work starting." );
      
      // Simulate time spent working.
      Thread::Sleep( (gcnew Random)->Next( 100, 2000 ) );
      
      // Signal that work is finished.
      Console::WriteLine( "Work ending." );
      dynamic_cast<AutoResetEvent^>(stateInfo)->Set();
   }

};

int main()
{
   Console::WriteLine( "Main starting." );
   AutoResetEvent^ autoEvent = gcnew AutoResetEvent( false );
   ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &WaitOne::WorkMethod ), autoEvent );
   
   // Wait for work method to signal.
   autoEvent->WaitOne(  );
   Console::WriteLine( "Work method signaled.\nMain ending." );
}
using System;
using System.Threading;

class WaitOne
{
    static AutoResetEvent autoEvent = new AutoResetEvent(false);

    static void Main()
    {
        Console.WriteLine("Main starting.");

        ThreadPool.QueueUserWorkItem(
            new WaitCallback(WorkMethod), autoEvent);

        // Wait for work method to signal.
        autoEvent.WaitOne();
        Console.WriteLine("Work method signaled.\nMain ending.");
    }

    static void WorkMethod(object stateInfo) 
    {
        Console.WriteLine("Work starting.");

        // Simulate time spent working.
        Thread.Sleep(new Random().Next(100, 2000));

        // Signal that work is finished.
        Console.WriteLine("Work ending.");
        ((AutoResetEvent)stateInfo).Set();
    }
}
Imports System.Threading

Public Class WaitOne

    Shared autoEvent As New AutoResetEvent(False)

    <MTAThread> _
    Shared Sub Main()
        Console.WriteLine("Main starting.")

        ThreadPool.QueueUserWorkItem(AddressOf WorkMethod, autoEvent)

        ' Wait for work method to signal.
        autoEvent.WaitOne()
        Console.WriteLine("Work method signaled.")
        Console.WriteLine("Main ending.")
    End Sub

    Shared Sub WorkMethod(stateInfo As Object) 
        Console.WriteLine("Work starting.")

        ' Simulate time spent working.
        Thread.Sleep(New Random().Next(100, 2000))

        ' Signal that work is finished.
        Console.WriteLine("Work ending.")
        CType(stateInfo, AutoResetEvent).Set()
    End Sub

End Class

Comentarios

AbandonedMutexException es nuevo en .NET Framework versión 2.0. En versiones anteriores, el WaitOne método devuelve true cuando se abandona una exclusión mutua. Una exclusión mutua abandonada suele indicar un error de codificación grave. En el caso de una exclusión mutua en todo el sistema, puede indicar que una aplicación se ha terminado abruptamente (por ejemplo, mediante el Administrador de tareas de Windows). La excepción contiene información útil para la depuración.

El autor de la llamada de este método se bloquea indefinidamente hasta que la instancia actual recibe una señal. Use este método para bloquear hasta WaitHandle que un recibe una señal de otro subproceso, como se genera cuando se completa una operación asincrónica. Para obtener más información, consulte la interfaz IAsyncResult.

Llamar a esta sobrecarga de método equivale a llamar a la sobrecarga del WaitOne(Int32, Boolean) método y especificar -1 o Timeout.Infinite para el primer parámetro y false para el segundo parámetro.

Invalide este método para personalizar el comportamiento de las clases derivadas.

Se aplica a

WaitOne(Int32)

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

Bloquea el subproceso actual hasta que el objeto WaitHandle actual recibe una señal, usando un entero de 32 bits con signo para especificar el intervalo de tiempo en milisegundos.

public:
 virtual bool WaitOne(int millisecondsTimeout);
public virtual bool WaitOne (int millisecondsTimeout);
abstract member WaitOne : int -> bool
override this.WaitOne : int -> bool
Public Overridable Function WaitOne (millisecondsTimeout As Integer) As Boolean

Parámetros

millisecondsTimeout
Int32

Número de milisegundos de espera o Infinite (-1) para esperar indefinidamente.

Devoluciones

true si la instancia actual recibe una señal; en caso contrario, false.

Excepciones

Ya se ha eliminado la instancia actual.

millisecondsTimeout es un número negativo distinto de-1, que representa un tiempo de espera infinito.

La espera finalizó porque un subproceso se cierra sin liberar una exclusión mutua.

La instancia actual es un proxy transparente para un objeto WaitHandle en otro dominio de aplicación.

Ejemplos

En el ejemplo de código siguiente se muestra cómo usar un identificador de espera para evitar que un proceso finalice mientras espera a que un subproceso en segundo plano termine de ejecutarse.

using namespace System;
using namespace System::Threading;
ref class WaitOne
{
private:
   WaitOne(){}


public:
   static void WorkMethod( Object^ stateInfo )
   {
      Console::WriteLine( "Work starting." );
      
      // Simulate time spent working.
      Thread::Sleep( (gcnew Random)->Next( 100, 2000 ) );
      
      // Signal that work is finished.
      Console::WriteLine( "Work ending." );
      dynamic_cast<AutoResetEvent^>(stateInfo)->Set();
   }

};

int main()
{
   Console::WriteLine( "Main starting." );
   AutoResetEvent^ autoEvent = gcnew AutoResetEvent( false );
   ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &WaitOne::WorkMethod ), autoEvent );
   
   // Wait for work method to signal.
   if ( autoEvent->WaitOne( 1000 ) )
   {
      Console::WriteLine( "Work method signaled." );
   }
   else
   {
      Console::WriteLine( "Timed out waiting for work "
      "method to signal." );
   }

   Console::WriteLine( "Main ending." );
}
using System;
using System.Threading;

class WaitOne
{
    static AutoResetEvent autoEvent = new AutoResetEvent(false);

    static void Main()
    {
        Console.WriteLine("Main starting.");

        ThreadPool.QueueUserWorkItem(
            new WaitCallback(WorkMethod), autoEvent);

        // Wait for work method to signal.
        if(autoEvent.WaitOne(1000))
        {
            Console.WriteLine("Work method signaled.");
        }
        else
        {
            Console.WriteLine("Timed out waiting for work " +
                "method to signal.");
        }
        Console.WriteLine("Main ending.");
    }

    static void WorkMethod(object stateInfo) 
    {
        Console.WriteLine("Work starting.");

        // Simulate time spent working.
        Thread.Sleep(new Random().Next(100, 2000));

        // Signal that work is finished.
        Console.WriteLine("Work ending.");
        ((AutoResetEvent)stateInfo).Set();
    }
}
Imports System.Threading

Public Class WaitOne

    Shared autoEvent As New AutoResetEvent(False)

    <MTAThread> _
    Shared Sub Main()
        Console.WriteLine("Main starting.")

        ThreadPool.QueueUserWorkItem(AddressOf WorkMethod, autoEvent)

        ' Wait for work method to signal.
        If autoEvent.WaitOne(1000) Then
            Console.WriteLine("Work method signaled.")
        Else
            Console.WriteLine("Timed out waiting for work " & _
                "method to signal.")
        End If

        Console.WriteLine("Main ending.")
    End Sub

    Shared Sub WorkMethod(stateInfo As Object) 
        Console.WriteLine("Work starting.")

        ' Simulate time spent working.
        Thread.Sleep(New Random().Next(100, 2000))

        ' Signal that work is finished.
        Console.WriteLine("Work ending.")
        CType(stateInfo, AutoResetEvent).Set()
    End Sub

End Class

Comentarios

Si millisecondsTimeout es cero, el método no se bloquea. Comprueba el estado del identificador de espera y devuelve inmediatamente.

El autor de la llamada de este método se bloquea hasta que la instancia actual recibe una señal o se agota el tiempo de espera. Use este método para bloquear hasta WaitHandle que un recibe una señal de otro subproceso, como se genera cuando se completa una operación asincrónica. Para obtener más información, consulte la interfaz IAsyncResult.

Invalide este método para personalizar el comportamiento de las clases derivadas.

Llamar a esta sobrecarga de método es la misma que llamar a la WaitOne(Int32, Boolean) sobrecarga y especificar false para exitContext.

Se aplica a

WaitOne(TimeSpan)

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

Bloquea el subproceso actual hasta que la instancia actual recibe una señal, usando TimeSpan para especificar el intervalo de tiempo.

public:
 virtual bool WaitOne(TimeSpan timeout);
public virtual bool WaitOne (TimeSpan timeout);
abstract member WaitOne : TimeSpan -> bool
override this.WaitOne : TimeSpan -> bool
Public Overridable Function WaitOne (timeout As TimeSpan) As Boolean

Parámetros

timeout
TimeSpan

Estructura TimeSpan que representa el número de milisegundos de espera o estructura TimeSpan que representa -1 milisegundos para esperar indefinidamente.

Devoluciones

true si la instancia actual recibe una señal; en caso contrario, false.

Excepciones

Ya se ha eliminado la instancia actual.

timeout es un número negativo distinto de -1 milisegundos, que representa un tiempo de espera infinito.

O bien

timeout es mayor que Int32.MaxValue.

La espera finalizó porque un subproceso se cierra sin liberar una exclusión mutua.

La instancia actual es un proxy transparente para un objeto WaitHandle en otro dominio de aplicación.

Comentarios

Si timeout es cero, el método no se bloquea. Comprueba el estado del identificador de espera y devuelve inmediatamente.

El autor de la llamada de este método se bloquea hasta que la instancia actual recibe una señal o se agota el tiempo de espera. Use este método para bloquear hasta WaitHandle que un recibe una señal de otro subproceso, como se genera cuando se completa una operación asincrónica. Para obtener más información, consulte la interfaz IAsyncResult.

Invalide este método para personalizar el comportamiento de las clases derivadas.

El valor máximo de timeout es Int32.MaxValue.

Llamar a esta sobrecarga de método es la misma que llamar a la WaitOne(TimeSpan, Boolean) sobrecarga y especificar false para exitContext.

Se aplica a

WaitOne(Int32, Boolean)

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

Bloquea el subproceso actual hasta que el objeto WaitHandle actual recibe una señal, usa un entero de 32 bits con signo para determinar el intervalo de tiempo y especifica si hay que salir del dominio de sincronización antes de la espera.

public:
 virtual bool WaitOne(int millisecondsTimeout, bool exitContext);
public virtual bool WaitOne (int millisecondsTimeout, bool exitContext);
abstract member WaitOne : int * bool -> bool
override this.WaitOne : int * bool -> bool
Public Overridable Function WaitOne (millisecondsTimeout As Integer, exitContext As Boolean) As Boolean

Parámetros

millisecondsTimeout
Int32

Número de milisegundos de espera o Infinite (-1) para esperar indefinidamente.

exitContext
Boolean

true para salir del dominio de sincronización del contexto antes de la espera (en caso de encontrarse en un contexto sincronizado) y volver a adquirirlo más tarde; de lo contrario, false.

Devoluciones

true si la instancia actual recibe una señal; en caso contrario, false.

Excepciones

Ya se ha eliminado la instancia actual.

millisecondsTimeout es un número negativo distinto de-1, que representa un tiempo de espera infinito.

La espera finalizó porque un subproceso se cierra sin liberar una exclusión mutua.

La instancia actual es un proxy transparente para un objeto WaitHandle en otro dominio de aplicación.

Ejemplos

En el ejemplo siguiente se muestra cómo se comporta la sobrecarga del WaitOne(Int32, Boolean) método cuando se llama a dentro de un dominio de sincronización. En primer lugar, un subproceso espera con exitContext establecido en false y se bloquea hasta que expire el tiempo de espera. Un segundo subproceso se ejecuta después de que finalice el primer subproceso y espere con exitContext establecido en true. La llamada para indicar el identificador de espera de este segundo subproceso no está bloqueado y el subproceso se completa antes del tiempo de espera.

using namespace System;
using namespace System::Threading;
using namespace System::Runtime::Remoting::Contexts;

[Synchronization(true)]
public ref class SyncingClass : ContextBoundObject
{
private:
    EventWaitHandle^ waitHandle;

public:
    SyncingClass()
    {
         waitHandle =
            gcnew EventWaitHandle(false, EventResetMode::ManualReset);
    }

    void Signal()
    {
        Console::WriteLine("Thread[{0:d4}]: Signalling...", Thread::CurrentThread->GetHashCode());
        waitHandle->Set();
    }

    void DoWait(bool leaveContext)
    {
        bool signalled;

        waitHandle->Reset();
        Console::WriteLine("Thread[{0:d4}]: Waiting...", Thread::CurrentThread->GetHashCode());
        signalled = waitHandle->WaitOne(3000, leaveContext);
        if (signalled)
        {
            Console::WriteLine("Thread[{0:d4}]: Wait released!!!", Thread::CurrentThread->GetHashCode());
        }
        else
        {
            Console::WriteLine("Thread[{0:d4}]: Wait timeout!!!", Thread::CurrentThread->GetHashCode());
        }
    }
};

public ref class TestSyncDomainWait
{
public:
    static void Main()
    {
        SyncingClass^ syncClass = gcnew SyncingClass();

        Thread^ runWaiter;

        Console::WriteLine("\nWait and signal INSIDE synchronization domain:\n");
        runWaiter = gcnew Thread(gcnew ParameterizedThreadStart(&TestSyncDomainWait::RunWaitKeepContext));
        runWaiter->Start(syncClass);
        Thread::Sleep(1000);
        Console::WriteLine("Thread[{0:d4}]: Signal...", Thread::CurrentThread->GetHashCode());
        // This call to Signal will block until the timeout in DoWait expires.
        syncClass->Signal();
        runWaiter->Join();

        Console::WriteLine("\nWait and signal OUTSIDE synchronization domain:\n");
        runWaiter = gcnew Thread(gcnew ParameterizedThreadStart(&TestSyncDomainWait::RunWaitLeaveContext));
        runWaiter->Start(syncClass);
        Thread::Sleep(1000);
        Console::WriteLine("Thread[{0:d4}]: Signal...", Thread::CurrentThread->GetHashCode());
        // This call to Signal is unblocked and will set the wait handle to
        // release the waiting thread.
        syncClass->Signal();
        runWaiter->Join();
    }

    static void RunWaitKeepContext(Object^ parm)
    {
        ((SyncingClass^)parm)->DoWait(false);
    }

    static void RunWaitLeaveContext(Object^ parm)
    {
        ((SyncingClass^)parm)->DoWait(true);
    }
};

int main()
{
    TestSyncDomainWait::Main();
}
// The output for the example program will be similar to the following:
//
// Wait and signal INSIDE synchronization domain:
//
// Thread[0004]: Waiting...
// Thread[0001]: Signal...
// Thread[0004]: Wait timeout!!!
// Thread[0001]: Signalling...
//
// Wait and signal OUTSIDE synchronization domain:
//
// Thread[0006]: Waiting...
// Thread[0001]: Signal...
// Thread[0001]: Signalling...
// Thread[0006]: Wait released!!!
using System;
using System.Threading;
using System.Runtime.Remoting.Contexts;

[Synchronization(true)]
public class SyncingClass : ContextBoundObject
{
    private EventWaitHandle waitHandle;

    public SyncingClass()
    {
         waitHandle =
            new EventWaitHandle(false, EventResetMode.ManualReset);
    }

    public void Signal()
    {
        Console.WriteLine("Thread[{0:d4}]: Signalling...", Thread.CurrentThread.GetHashCode());
        waitHandle.Set();
    }

    public void DoWait(bool leaveContext)
    {
        bool signalled;

        waitHandle.Reset();
        Console.WriteLine("Thread[{0:d4}]: Waiting...", Thread.CurrentThread.GetHashCode());
        signalled = waitHandle.WaitOne(3000, leaveContext);
        if (signalled)
        {
            Console.WriteLine("Thread[{0:d4}]: Wait released!!!", Thread.CurrentThread.GetHashCode());
        }
        else
        {
            Console.WriteLine("Thread[{0:d4}]: Wait timeout!!!", Thread.CurrentThread.GetHashCode());
        }
    }
}

public class TestSyncDomainWait
{
    public static void Main()
    {
        SyncingClass syncClass = new SyncingClass();

        Thread runWaiter;

        Console.WriteLine("\nWait and signal INSIDE synchronization domain:\n");
        runWaiter = new Thread(RunWaitKeepContext);
        runWaiter.Start(syncClass);
        Thread.Sleep(1000);
        Console.WriteLine("Thread[{0:d4}]: Signal...", Thread.CurrentThread.GetHashCode());
        // This call to Signal will block until the timeout in DoWait expires.
        syncClass.Signal();
        runWaiter.Join();

        Console.WriteLine("\nWait and signal OUTSIDE synchronization domain:\n");
        runWaiter = new Thread(RunWaitLeaveContext);
        runWaiter.Start(syncClass);
        Thread.Sleep(1000);
        Console.WriteLine("Thread[{0:d4}]: Signal...", Thread.CurrentThread.GetHashCode());
        // This call to Signal is unblocked and will set the wait handle to
        // release the waiting thread.
        syncClass.Signal();
        runWaiter.Join();
    }

    public static void RunWaitKeepContext(object parm)
    {
        ((SyncingClass)parm).DoWait(false);
    }

    public static void RunWaitLeaveContext(object parm)
    {
        ((SyncingClass)parm).DoWait(true);
    }
}

// The output for the example program will be similar to the following:
//
// Wait and signal INSIDE synchronization domain:
//
// Thread[0004]: Waiting...
// Thread[0001]: Signal...
// Thread[0004]: Wait timeout!!!
// Thread[0001]: Signalling...
//
// Wait and signal OUTSIDE synchronization domain:
//
// Thread[0006]: Waiting...
// Thread[0001]: Signal...
// Thread[0001]: Signalling...
// Thread[0006]: Wait released!!!
Imports System.Threading
Imports System.Runtime.Remoting.Contexts

<Synchronization(true)>
Public Class SyncingClass
    Inherits ContextBoundObject
    
    Private waitHandle As EventWaitHandle

    Public Sub New()
         waitHandle = New EventWaitHandle(false, EventResetMode.ManualReset)
    End Sub

    Public Sub Signal()
        Console.WriteLine("Thread[{0:d4}]: Signalling...", Thread.CurrentThread.GetHashCode())
        waitHandle.Set()
    End Sub

    Public Sub DoWait(leaveContext As Boolean)
        Dim signalled As Boolean

        waitHandle.Reset()
        Console.WriteLine("Thread[{0:d4}]: Waiting...", Thread.CurrentThread.GetHashCode())
        signalled = waitHandle.WaitOne(3000, leaveContext)
        If signalled Then
            Console.WriteLine("Thread[{0:d4}]: Wait released!!!", Thread.CurrentThread.GetHashCode())
        Else
            Console.WriteLine("Thread[{0:d4}]: Wait timeout!!!", Thread.CurrentThread.GetHashCode())
        End If
    End Sub
End Class

Public Class TestSyncDomainWait
    Public Shared Sub Main()
        Dim syncClass As New SyncingClass()

        Dim runWaiter As Thread

        Console.WriteLine(Environment.NewLine + "Wait and signal INSIDE synchronization domain:" + Environment.NewLine)
        runWaiter = New Thread(AddressOf RunWaitKeepContext)
        runWaiter.Start(syncClass)
        Thread.Sleep(1000)
        Console.WriteLine("Thread[{0:d4}]: Signal...", Thread.CurrentThread.GetHashCode())
        ' This call to Signal will block until the timeout in DoWait expires.
        syncClass.Signal()
        runWaiter.Join()

        Console.WriteLine(Environment.NewLine + "Wait and signal OUTSIDE synchronization domain:" + Environment.NewLine)
        runWaiter = New Thread(AddressOf RunWaitLeaveContext)
        runWaiter.Start(syncClass)
        Thread.Sleep(1000)
        Console.WriteLine("Thread[{0:d4}]: Signal...", Thread.CurrentThread.GetHashCode())
        ' This call to Signal is unblocked and will set the wait handle to
        ' release the waiting thread.
        syncClass.Signal()
        runWaiter.Join()
    End Sub

    Public Shared Sub RunWaitKeepContext(parm As Object)
        Dim syncClass As SyncingClass = CType(parm, SyncingClass)
        syncClass.DoWait(False)
    End Sub

    Public Shared Sub RunWaitLeaveContext(parm As Object)
        Dim syncClass As SyncingClass = CType(parm, SyncingClass)
        syncClass.DoWait(True)
    End Sub
End Class

' The output for the example program will be similar to the following:
'
' Wait and signal INSIDE synchronization domain:
'
' Thread[0004]: Waiting...
' Thread[0001]: Signal...
' Thread[0004]: Wait timeout!!!
' Thread[0001]: Signalling...
'
' Wait and signal OUTSIDE synchronization domain:
'
' Thread[0006]: Waiting...
' Thread[0001]: Signal...
' Thread[0001]: Signalling...
' Thread[0006]: Wait released!!!

Comentarios

Si millisecondsTimeout es cero, el método no se bloquea. Comprueba el estado del identificador de espera y devuelve inmediatamente.

Si se abandona una exclusión mutua, se produce una AbandonedMutexException excepción . Una exclusión mutua abandonada suele indicar un error de codificación grave. En el caso de una exclusión mutua en todo el sistema, puede indicar que una aplicación se ha terminado abruptamente (por ejemplo, mediante el Administrador de tareas de Windows). La excepción contiene información útil para la depuración.

El autor de la llamada de este método se bloquea hasta que la instancia actual recibe una señal o se agota el tiempo de espera. Use este método para bloquear hasta WaitHandle que un recibe una señal de otro subproceso, como se genera cuando se completa una operación asincrónica. Para obtener más información, consulte la interfaz IAsyncResult.

Invalide este método para personalizar el comportamiento de las clases derivadas.

Salir del contexto

El exitContext parámetro no tiene ningún efecto a menos que se llame a este método desde dentro de un contexto administrado no predeterminado. El contexto administrado puede no ser predeterminado si el subproceso está dentro de una llamada a una instancia de una clase derivada de ContextBoundObject. Incluso si actualmente está ejecutando un método en una clase que no se deriva de ContextBoundObject, como String, puede estar en un contexto no predeterminado si ContextBoundObject está en la pila en el dominio de aplicación actual.

Cuando el código se ejecuta en un contexto no predeterminado, especificando true para exitContext que el subproceso salga del contexto administrado no predeterminado (es decir, para realizar la transición al contexto predeterminado) antes de ejecutar este método. El subproceso vuelve al contexto no predeterminado original una vez completada la llamada a este método.

Salir del contexto puede ser útil cuando la clase enlazada al contexto tiene el SynchronizationAttribute atributo . En ese caso, todas las llamadas a los miembros de la clase se sincronizan automáticamente y el dominio de sincronización es todo el cuerpo de código de la clase. Si el código de la pila de llamadas de un miembro llama a este método y especifica para exitContext, el subproceso true sale del dominio de sincronización, lo que permite que un subproceso bloqueado en una llamada a cualquier miembro del objeto continúe. Cuando este método vuelve, el subproceso que realizó la llamada debe esperar a volver a escribir el dominio de sincronización.

Se aplica a

WaitOne(TimeSpan, Boolean)

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

Bloquea el subproceso actual hasta que la instancia actual recibe una señal; usa TimeSpan para determinar el intervalo de tiempo y especifica si hay que abandonar el dominio de sincronización antes de la espera.

public:
 virtual bool WaitOne(TimeSpan timeout, bool exitContext);
public virtual bool WaitOne (TimeSpan timeout, bool exitContext);
abstract member WaitOne : TimeSpan * bool -> bool
override this.WaitOne : TimeSpan * bool -> bool
Public Overridable Function WaitOne (timeout As TimeSpan, exitContext As Boolean) As Boolean

Parámetros

timeout
TimeSpan

Estructura TimeSpan que representa el número de milisegundos de espera o estructura TimeSpan que representa -1 milisegundos para esperar indefinidamente.

exitContext
Boolean

true para salir del dominio de sincronización del contexto antes de la espera (en caso de encontrarse en un contexto sincronizado) y volver a adquirirlo más tarde; de lo contrario, false.

Devoluciones

true si la instancia actual recibe una señal; en caso contrario, false.

Excepciones

Ya se ha eliminado la instancia actual.

timeout es un número negativo distinto de -1 milisegundos, que representa un tiempo de espera infinito.

O bien

timeout es mayor que Int32.MaxValue.

La espera finalizó porque un subproceso se cierra sin liberar una exclusión mutua.

La instancia actual es un proxy transparente para un objeto WaitHandle en otro dominio de aplicación.

Ejemplos

En el ejemplo de código siguiente se muestra cómo usar un identificador de espera para evitar que un proceso finalice mientras espera a que un subproceso en segundo plano termine de ejecutarse.

using namespace System;
using namespace System::Threading;
ref class WaitOne
{
private:
   WaitOne(){}


public:
   static void WorkMethod( Object^ stateInfo )
   {
      Console::WriteLine( "Work starting." );
      
      // Simulate time spent working.
      Thread::Sleep( (gcnew Random)->Next( 100, 2000 ) );
      
      // Signal that work is finished.
      Console::WriteLine( "Work ending." );
      dynamic_cast<AutoResetEvent^>(stateInfo)->Set();
   }

};

int main()
{
   Console::WriteLine( "Main starting." );
   AutoResetEvent^ autoEvent = gcnew AutoResetEvent( false );
   ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &WaitOne::WorkMethod ), autoEvent );
   
   // Wait for work method to signal.
   if ( autoEvent->WaitOne( TimeSpan(0,0,1), false ) )
   {
      Console::WriteLine( "Work method signaled." );
   }
   else
   {
      Console::WriteLine( "Timed out waiting for work "
      "method to signal." );
   }

   Console::WriteLine( "Main ending." );
}
using System;
using System.Threading;

class WaitOne
{
    static AutoResetEvent autoEvent = new AutoResetEvent(false);

    static void Main()
    {
        Console.WriteLine("Main starting.");

        ThreadPool.QueueUserWorkItem(
            new WaitCallback(WorkMethod), autoEvent);

        // Wait for work method to signal.
        if(autoEvent.WaitOne(new TimeSpan(0, 0, 1), false))
        {
            Console.WriteLine("Work method signaled.");
        }
        else
        {
            Console.WriteLine("Timed out waiting for work " +
                "method to signal.");
        }
        Console.WriteLine("Main ending.");
    }

    static void WorkMethod(object stateInfo) 
    {
        Console.WriteLine("Work starting.");

        // Simulate time spent working.
        Thread.Sleep(new Random().Next(100, 2000));

        // Signal that work is finished.
        Console.WriteLine("Work ending.");
        ((AutoResetEvent)stateInfo).Set();
    }
}
Imports System.Threading

Public Class WaitOne

    Shared autoEvent As New AutoResetEvent(False)

    <MTAThread> _
    Shared Sub Main()
        Console.WriteLine("Main starting.")

        ThreadPool.QueueUserWorkItem(AddressOf WorkMethod, autoEvent)

        ' Wait for work method to signal.
        If autoEvent.WaitOne(New TimeSpan(0, 0, 1), False) Then
            Console.WriteLine("Work method signaled.")
        Else
            Console.WriteLine("Timed out waiting for work " & _
                "method to signal.")
        End If

        Console.WriteLine("Main ending.")
    End Sub

    Shared Sub WorkMethod(stateInfo As Object) 
        Console.WriteLine("Work starting.")

        ' Simulate time spent working.
        Thread.Sleep(New Random().Next(100, 2000))

        ' Signal that work is finished.
        Console.WriteLine("Work ending.")
        CType(stateInfo, AutoResetEvent).Set()
    End Sub

End Class

Comentarios

Si timeout es cero, el método no se bloquea. Comprueba el estado del identificador de espera y devuelve inmediatamente.

Si se abandona una exclusión mutua, se produce una AbandonedMutexException excepción . Una exclusión mutua abandonada suele indicar un error de codificación grave. En el caso de una exclusión mutua en todo el sistema, puede indicar que una aplicación se ha terminado abruptamente (por ejemplo, mediante el Administrador de tareas de Windows). La excepción contiene información útil para la depuración.

El autor de la llamada de este método se bloquea hasta que la instancia actual recibe una señal o se agota el tiempo de espera. Use este método para bloquear hasta que un WaitHandle recibe una señal de otro subproceso, como se genera cuando se completa una operación asincrónica. Para obtener más información, consulte la interfaz IAsyncResult.

Invalide este método para personalizar el comportamiento de las clases derivadas.

El valor máximo de timeout es Int32.MaxValue.

Salir del contexto

El exitContext parámetro no tiene ningún efecto a menos que se llame a este método desde dentro de un contexto administrado no predeterminado. El contexto administrado puede ser no predeterminado si el subproceso está dentro de una llamada a una instancia de una clase derivada de ContextBoundObject. Incluso si actualmente está ejecutando un método en una clase que no se deriva de ContextBoundObject, como String, puede estar en un contexto no predeterminado si ContextBoundObject está en la pila en el dominio de aplicación actual.

Cuando el código se ejecuta en un contexto no predeterminado, al especificar true para exitContext que el subproceso salga del contexto administrado no predeterminado (es decir, para realizar la transición al contexto predeterminado) antes de ejecutar este método. El subproceso vuelve al contexto no predeterminado original una vez completada la llamada a este método.

Salir del contexto puede ser útil cuando la clase enlazada al contexto tiene el SynchronizationAttribute atributo . En ese caso, todas las llamadas a los miembros de la clase se sincronizan automáticamente y el dominio de sincronización es todo el cuerpo de código de la clase. Si el código de la pila de llamadas de un miembro llama a este método y especifica para exitContext, el subproceso true sale del dominio de sincronización, lo que permite que un subproceso bloqueado en una llamada a cualquier miembro del objeto continúe. Cuando este método vuelve, el subproceso que realizó la llamada debe esperar a volver a escribir el dominio de sincronización.

Se aplica a