Compartilhar via


WaitHandle.WaitOne Método

Definição

Bloqueia o thread atual até que o WaitHandle atual receba um sinal.

Sobrecargas

WaitOne()

Bloqueia o thread atual até que o WaitHandle atual receba um sinal.

WaitOne(Int32)

Bloqueia o thread atual até que o WaitHandle atual receba um sinal, usando um inteiro com sinal de 32 bits para especificar o intervalo de tempo em milissegundos.

WaitOne(TimeSpan)

Bloqueia o thread atual até que a instância atual receba um sinal, usando um TimeSpan para especificar o intervalo de tempo.

WaitOne(Int32, Boolean)

Bloqueia o thread atual até que o WaitHandle atual receba um sinal, usando um inteiro com sinal de 32 bits para especificar o intervalo de tempo e especificar se sairá do domínio de sincronização antes da espera.

WaitOne(TimeSpan, Boolean)

Bloqueia o thread atual até que a instância atual receba um sinal, usando um TimeSpan para especificar o intervalo de tempo e especificar se sairá do domínio de sincronização antes da espera.

WaitOne()

Origem:
WaitHandle.cs
Origem:
WaitHandle.cs
Origem:
WaitHandle.cs

Bloqueia o thread atual até que o WaitHandle atual receba um sinal.

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

Retornos

true se a instância atual receber um sinal. Se a instância atual nunca for sinalizada, WaitOne() nunca será retornado.

Exceções

A instância atual já foi descartada.

A espera foi concluída porque um thread foi encerrado sem liberar um mutex.

A instância atual é um proxy transparente para um WaitHandle em outro domínio de aplicativo.

Exemplos

O exemplo de código a seguir mostra como usar um identificador de espera para impedir que um processo seja encerrado enquanto aguarda a conclusão da execução de um thread em segundo plano.

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

Comentários

AbandonedMutexExceptioné novo no .NET Framework versão 2.0. Em versões anteriores, o WaitOne método retorna true quando um mutex é abandonado. Um mutex abandonado geralmente indica um erro grave de codificação. No caso de um mutex em todo o sistema, isso pode indicar que um aplicativo foi encerrado abruptamente (por exemplo, usando o Gerenciador de Tarefas do Windows). A exceção contém informações úteis para depuração.

O chamador desse método é bloqueado indefinidamente até que a instância atual receba um sinal. Use esse método para bloquear até que um WaitHandle receba um sinal de outro thread, como é gerado quando uma operação assíncrona é concluída. Para obter mais informações, consulte a IAsyncResult interface .

Chamar essa sobrecarga de método é equivalente a chamar a sobrecarga do WaitOne(Int32, Boolean) método e especificar -1 ou Timeout.Infinite para o primeiro parâmetro e false para o segundo parâmetro.

Substitua esse método para personalizar o comportamento de classes derivadas.

Aplica-se a

WaitOne(Int32)

Origem:
WaitHandle.cs
Origem:
WaitHandle.cs
Origem:
WaitHandle.cs

Bloqueia o thread atual até que o WaitHandle atual receba um sinal, usando um inteiro com sinal de 32 bits para especificar o intervalo de tempo em milissegundos.

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

O número de milissegundos para aguardar ou Infinite (- 1) para aguardar indefinidamente.

Retornos

true se a instância atual receber um sinal, caso contrário, false.

Exceções

A instância atual já foi descartada.

millisecondsTimeout é um número negativo diferente de -1, que representa um tempo limite infinito.

A espera foi concluída porque um thread foi encerrado sem liberar um mutex.

A instância atual é um proxy transparente para um WaitHandle em outro domínio de aplicativo.

Exemplos

O exemplo de código a seguir mostra como usar um identificador de espera para impedir que um processo seja encerrado enquanto aguarda a conclusão da execução de um thread em segundo plano.

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

Comentários

Se millisecondsTimeout for zero, o método não bloqueará. Ele testa o estado do identificador de espera e retorna imediatamente.

O chamador desse método é bloqueado até que a instância atual receba um sinal ou um tempo limite ocorra. Use esse método para bloquear até que um WaitHandle receba um sinal de outro thread, como é gerado quando uma operação assíncrona é concluída. Para obter mais informações, consulte a IAsyncResult interface .

Substitua esse método para personalizar o comportamento de classes derivadas.

Chamar essa sobrecarga de método é o mesmo que chamar a WaitOne(Int32, Boolean) sobrecarga e especificar false para exitContext.

Aplica-se a

WaitOne(TimeSpan)

Origem:
WaitHandle.cs
Origem:
WaitHandle.cs
Origem:
WaitHandle.cs

Bloqueia o thread atual até que a instância atual receba um sinal, usando um TimeSpan para especificar o intervalo de tempo.

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

Um TimeSpan que representa o número de milissegundos para aguardar ou um TimeSpan que representa -1 milissegundos para aguardar indefinidamente.

Retornos

true se a instância atual receber um sinal, caso contrário, false.

Exceções

A instância atual já foi descartada.

timeout é um número negativo diferente de -1 milissegundo, que representa um tempo limite infinito.

- ou -

timeout é maior que Int32.MaxValue.

A espera foi concluída porque um thread foi encerrado sem liberar um mutex.

A instância atual é um proxy transparente para um WaitHandle em outro domínio de aplicativo.

Comentários

Se timeout for zero, o método não bloqueará. Ele testa o estado do identificador de espera e retorna imediatamente.

O chamador desse método é bloqueado até que a instância atual receba um sinal ou um tempo limite ocorra. Use esse método para bloquear até que um WaitHandle receba um sinal de outro thread, como é gerado quando uma operação assíncrona é concluída. Para obter mais informações, consulte a IAsyncResult interface .

Substitua esse método para personalizar o comportamento de classes derivadas.

O valor máximo para timeout é Int32.MaxValue.

Chamar essa sobrecarga de método é o mesmo que chamar a WaitOne(TimeSpan, Boolean) sobrecarga e especificar false para exitContext.

Aplica-se a

WaitOne(Int32, Boolean)

Origem:
WaitHandle.cs
Origem:
WaitHandle.cs
Origem:
WaitHandle.cs

Bloqueia o thread atual até que o WaitHandle atual receba um sinal, usando um inteiro com sinal de 32 bits para especificar o intervalo de tempo e especificar se sairá do domínio de sincronização antes da 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

O número de milissegundos para aguardar ou Infinite (- 1) para aguardar indefinidamente.

exitContext
Boolean

true para sair do domínio de sincronização do contexto antes do tempo de espera (se estiver em um contexto sincronizado) e readquiri-lo posteriormente; caso contrário, false.

Retornos

true se a instância atual receber um sinal, caso contrário, false.

Exceções

A instância atual já foi descartada.

millisecondsTimeout é um número negativo diferente de -1, que representa um tempo limite infinito.

A espera foi concluída porque um thread foi encerrado sem liberar um mutex.

A instância atual é um proxy transparente para um WaitHandle em outro domínio de aplicativo.

Exemplos

O exemplo a seguir mostra como a sobrecarga do WaitOne(Int32, Boolean) método se comporta quando é chamada dentro de um domínio de sincronização. Primeiro, um thread aguarda com definido como exitContextfalse e bloqueia até que o tempo limite de espera expire. Um segundo thread é executado após o término do primeiro thread e aguarda com definido truecomo exitContext . A chamada para sinalizar o identificador de espera para esse segundo thread não está bloqueada e o thread é concluído antes do tempo limite 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!!!

Comentários

Se millisecondsTimeout for zero, o método não bloqueará. Ele testa o estado do identificador de espera e retorna imediatamente.

Se um mutex for abandonado, um AbandonedMutexException será lançado. Um mutex abandonado geralmente indica um erro grave de codificação. No caso de um mutex em todo o sistema, isso pode indicar que um aplicativo foi encerrado abruptamente (por exemplo, usando o Gerenciador de Tarefas do Windows). A exceção contém informações úteis para depuração.

O chamador desse método é bloqueado até que a instância atual receba um sinal ou um tempo limite ocorra. Use esse método para bloquear até que um WaitHandle receba um sinal de outro thread, como é gerado quando uma operação assíncrona é concluída. Para obter mais informações, consulte a IAsyncResult interface .

Substitua esse método para personalizar o comportamento de classes derivadas.

Saindo do contexto

O exitContext parâmetro não tem efeito, a menos que esse método seja chamado de dentro de um contexto gerenciado não padrão. O contexto gerenciado poderá não ser padrão se o thread estiver dentro de uma chamada para uma instância de uma classe derivada de ContextBoundObject. Mesmo que você esteja executando um método em uma classe que não é derivada de ContextBoundObject, como String, você pode estar em um contexto não padrão se um ContextBoundObject estiver em sua pilha no domínio do aplicativo atual.

Quando o código está em execução em um contexto não padrão, especificar true para exitContext faz com que o thread saia do contexto gerenciado não padrão (ou seja, fazer a transição para o contexto padrão) antes de executar esse método. O thread retorna ao contexto não padrão original após a conclusão da chamada para esse método.

Sair do contexto pode ser útil quando a classe associada ao contexto tem o SynchronizationAttribute atributo . Nesse caso, todas as chamadas para membros da classe são sincronizadas automaticamente e o domínio de sincronização é todo o corpo do código para a classe. Se o código na pilha de chamadas de um membro chamar esse método e especificar true para exitContext, o thread sairá do domínio de sincronização, o que permitirá que um thread bloqueado em uma chamada para qualquer membro do objeto continue. Quando esse método retorna, o thread que fez a chamada deve aguardar para inserir novamente o domínio de sincronização.

Aplica-se a

WaitOne(TimeSpan, Boolean)

Origem:
WaitHandle.cs
Origem:
WaitHandle.cs
Origem:
WaitHandle.cs

Bloqueia o thread atual até que a instância atual receba um sinal, usando um TimeSpan para especificar o intervalo de tempo e especificar se sairá do domínio de sincronização antes da 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

Um TimeSpan que representa o número de milissegundos para aguardar ou um TimeSpan que representa -1 milissegundos para aguardar indefinidamente.

exitContext
Boolean

true para sair do domínio de sincronização do contexto antes do tempo de espera (se estiver em um contexto sincronizado) e readquiri-lo posteriormente; caso contrário, false.

Retornos

true se a instância atual receber um sinal, caso contrário, false.

Exceções

A instância atual já foi descartada.

timeout é um número negativo diferente de -1 milissegundo, que representa um tempo limite infinito.

- ou -

timeout é maior que Int32.MaxValue.

A espera foi concluída porque um thread foi encerrado sem liberar um mutex.

A instância atual é um proxy transparente para um WaitHandle em outro domínio de aplicativo.

Exemplos

O exemplo de código a seguir mostra como usar um identificador de espera para impedir que um processo seja encerrado enquanto aguarda a conclusão da execução de um thread em segundo plano.

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

Comentários

Se timeout for zero, o método não bloqueará. Ele testa o estado do identificador de espera e retorna imediatamente.

Se um mutex for abandonado, um AbandonedMutexException será gerado. Um mutex abandonado geralmente indica um erro grave de codificação. No caso de um mutex em todo o sistema, pode indicar que um aplicativo foi encerrado abruptamente (por exemplo, usando o Gerenciador de Tarefas do Windows). A exceção contém informações úteis para depuração.

O chamador desse método bloqueia até que a instância atual receba um sinal ou um tempo limite ocorra. Use esse método para bloquear até que um WaitHandle receba um sinal de outro thread, como é gerado quando uma operação assíncrona é concluída. Para obter mais informações, consulte a IAsyncResult interface .

Substitua esse método para personalizar o comportamento de classes derivadas.

O valor máximo para timeout é Int32.MaxValue.

Saindo do contexto

O exitContext parâmetro não tem efeito, a menos que esse método seja chamado de dentro de um contexto gerenciado não padrão. O contexto gerenciado poderá ser não padrão se o thread estiver dentro de uma chamada para uma instância de uma classe derivada de ContextBoundObject. Mesmo que você esteja executando um método em uma classe que não é derivada de ContextBoundObject, como String, você pode estar em um contexto não padrão se um ContextBoundObject estiver em sua pilha no domínio do aplicativo atual.

Quando o código está sendo executado em um contexto não padrão, especificar true para exitContext faz com que o thread saia do contexto gerenciado não padrão (ou seja, fazer a transição para o contexto padrão) antes de executar esse método. O thread retorna ao contexto não padrão original após a conclusão da chamada para esse método.

Sair do contexto pode ser útil quando a classe associada ao contexto tem o SynchronizationAttribute atributo . Nesse caso, todas as chamadas para membros da classe são sincronizadas automaticamente e o domínio de sincronização é todo o corpo do código para a classe . Se o código na pilha de chamadas de um membro chamar esse método e especificar true para exitContext, o thread sairá do domínio de sincronização, o que permitirá que um thread bloqueado em uma chamada para qualquer membro do objeto prossiga. Quando esse método retorna, o thread que fez a chamada deve aguardar para reentrada no domínio de sincronização.

Aplica-se a