Partager via


WaitHandle.WaitOne Méthode

Définition

Bloque le thread actuel jusqu'à ce que le WaitHandle actuel reçoive un signal.

Surcharges

WaitOne()

Bloque le thread actuel jusqu'à ce que le WaitHandle actuel reçoive un signal.

WaitOne(Int32)

Bloque le thread actuel jusqu'à ce que le WaitHandle actuel reçoive un signal, en utilisant un entier signé 32 bits pour spécifier l'intervalle de temps.

WaitOne(TimeSpan)

Bloque le thread actuel jusqu'à ce que l'instance actuelle reçoive un signal, en utilisant une valeur TimeSpan pour spécifier l'intervalle de temps.

WaitOne(Int32, Boolean)

Bloque le thread actuel jusqu’à ce que le WaitHandle actuel reçoive un signal, en utilisant un entier signé 32 bits pour spécifier l’intervalle de temps et en spécifiant s’il faut quitter le domaine de synchronisation avant l’attente.

WaitOne(TimeSpan, Boolean)

Bloque le thread actuel jusqu'à ce que l'instance actuelle reçoive un signal, en utilisant une valeur TimeSpan pour spécifier l'intervalle de temps et en spécifiant s'il faut quitter le domaine de synchronisation avant l'attente.

WaitOne()

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

Bloque le thread actuel jusqu'à ce que le WaitHandle actuel reçoive un signal.

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

Retours

true si l'instance actuelle reçoit un signal. Si l'instance actuelle ne reçoit jamais de signal, WaitOne() ne retourne jamais.

Exceptions

L’instance actuelle a déjà été supprimée.

L’attente s’est arrêtée, car un thread s’est terminé sans libérer de mutex.

L'instance actuelle est un proxy transparent pour un WaitHandle dans un autre domaine d'application.

Exemples

L’exemple de code suivant montre comment utiliser un handle d’attente pour empêcher un processus de se terminer pendant qu’il attend qu’un thread d’arrière-plan se termine.

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

Remarques

AbandonedMutexException est nouveau dans .NET Framework version 2.0. Dans les versions précédentes, la WaitOne méthode retourne true quand un mutex est abandonné. Un mutex abandonné indique souvent une erreur de codage grave. Dans le cas d’un mutex à l’échelle du système, cela peut indiquer qu’une application a été arrêtée brusquement (par exemple, à l’aide du Gestionnaire des tâches Windows). L’exception contient des informations utiles pour le débogage.

L’appelant de cette méthode se bloque indéfiniment jusqu’à ce que le instance actuel reçoive un signal. Utilisez cette méthode pour bloquer jusqu’à ce qu’un WaitHandle reçoit un signal d’un autre thread, tel qu’il est généré à la fin d’une opération asynchrone. Pour plus d’informations, consultez l’interface IAsyncResult .

Appeler cette surcharge de méthode revient à appeler la WaitOne(Int32, Boolean) surcharge de méthode et à spécifier -1 ou Timeout.Infinite pour le premier paramètre et false pour le deuxième paramètre.

Remplacez cette méthode pour personnaliser le comportement des classes dérivées.

S’applique à

WaitOne(Int32)

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

Bloque le thread actuel jusqu'à ce que le WaitHandle actuel reçoive un signal, en utilisant un entier signé 32 bits pour spécifier l'intervalle de temps.

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

Paramètres

millisecondsTimeout
Int32

Nombre de millisecondes à attendre, ou Infinite (-1) pour un délai d'attente infini.

Retours

true si l'instance actuelle reçoit un signal ; sinon, false.

Exceptions

L’instance actuelle a déjà été supprimée.

millisecondsTimeout est un nombre négatif différent de -1, qui représente un délai d’attente infini.

L’attente s’est arrêtée, car un thread s’est terminé sans libérer de mutex.

L'instance actuelle est un proxy transparent pour un WaitHandle dans un autre domaine d'application.

Exemples

L’exemple de code suivant montre comment utiliser un handle d’attente pour empêcher un processus de se terminer pendant qu’il attend qu’un thread d’arrière-plan se termine.

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

Remarques

Si millisecondsTimeout est zéro, la méthode ne bloque pas. Il teste l’état du handle d’attente et retourne immédiatement.

L’appelant de cette méthode bloque jusqu’à ce que le instance actuel reçoive un signal ou qu’un délai d’attente se produise. Utilisez cette méthode pour bloquer jusqu’à ce qu’un WaitHandle reçoit un signal d’un autre thread, tel qu’il est généré à la fin d’une opération asynchrone. Pour plus d’informations, consultez l’interface IAsyncResult .

Remplacez cette méthode pour personnaliser le comportement des classes dérivées.

L’appel de cette surcharge de méthode revient à appeler la WaitOne(Int32, Boolean) surcharge et à false spécifier pour exitContext.

S’applique à

WaitOne(TimeSpan)

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

Bloque le thread actuel jusqu'à ce que l'instance actuelle reçoive un signal, en utilisant une valeur TimeSpan pour spécifier l'intervalle de temps.

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

Paramètres

timeout
TimeSpan

TimeSpan qui représente le nombre de millièmes de secondes à attendre ou TimeSpan qui représente -1 millième de seconde, pour attendre indéfiniment.

Retours

true si l'instance actuelle reçoit un signal ; sinon, false.

Exceptions

L’instance actuelle a déjà été supprimée.

timeout est un nombre négatif différent de -1 milliseconde, qui représente un délai d’attente infini.

-ou-

timeout est supérieur à Int32.MaxValue.

L’attente s’est arrêtée, car un thread s’est terminé sans libérer de mutex.

L'instance actuelle est un proxy transparent pour un WaitHandle dans un autre domaine d'application.

Remarques

Si timeout est zéro, la méthode ne bloque pas. Il teste l’état du handle d’attente et retourne immédiatement.

L’appelant de cette méthode bloque jusqu’à ce que le instance actuel reçoive un signal ou qu’un délai d’attente se produise. Utilisez cette méthode pour bloquer jusqu’à ce qu’un WaitHandle reçoit un signal d’un autre thread, tel qu’il est généré à la fin d’une opération asynchrone. Pour plus d’informations, consultez l’interface IAsyncResult .

Remplacez cette méthode pour personnaliser le comportement des classes dérivées.

La valeur maximale pour timeout est Int32.MaxValue.

L’appel de cette surcharge de méthode revient à appeler la WaitOne(TimeSpan, Boolean) surcharge et à false spécifier pour exitContext.

S’applique à

WaitOne(Int32, Boolean)

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

Bloque le thread actuel jusqu’à ce que le WaitHandle actuel reçoive un signal, en utilisant un entier signé 32 bits pour spécifier l’intervalle de temps et en spécifiant s’il faut quitter le domaine de synchronisation avant l’attente.

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

Paramètres

millisecondsTimeout
Int32

Nombre de millisecondes à attendre, ou Infinite (-1) pour un délai d'attente infini.

exitContext
Boolean

true pour quitter le domaine de synchronisation du contexte avant l'attente (dans le cas d'un contexte synchronisé) et l'acquérir à nouveau ensuite ; sinon, false.

Retours

true si l'instance actuelle reçoit un signal ; sinon, false.

Exceptions

L’instance actuelle a déjà été supprimée.

millisecondsTimeout est un nombre négatif différent de -1, qui représente un délai d’attente infini.

L’attente s’est arrêtée, car un thread s’est terminé sans libérer de mutex.

L'instance actuelle est un proxy transparent pour un WaitHandle dans un autre domaine d'application.

Exemples

L’exemple suivant montre comment la surcharge de WaitOne(Int32, Boolean) méthode se comporte lorsqu’elle est appelée dans un domaine de synchronisation. Tout d’abord, un thread attend avec exitContext défini sur et bloque jusqu’à false l’expiration du délai d’attente. Un deuxième thread s’exécute une fois que le premier thread se termine et attend avec exitContext la valeur définie sur true. L’appel pour signaler la poignée d’attente de ce deuxième thread n’est pas bloqué et le thread se termine avant le délai d’attente.

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!!!

Remarques

Si millisecondsTimeout est zéro, la méthode ne bloque pas. Il teste l’état du handle d’attente et retourne immédiatement.

Si un mutex est abandonné, un AbandonedMutexException est levée. Un mutex abandonné indique souvent une erreur de codage grave. Dans le cas d’un mutex à l’échelle du système, cela peut indiquer qu’une application a été arrêtée brusquement (par exemple, à l’aide du Gestionnaire des tâches Windows). L’exception contient des informations utiles pour le débogage.

L’appelant de cette méthode bloque jusqu’à ce que le instance actuel reçoive un signal ou qu’un délai d’attente se produise. Utilisez cette méthode pour bloquer jusqu’à ce qu’un WaitHandle reçoit un signal d’un autre thread, tel qu’il est généré à la fin d’une opération asynchrone. Pour plus d’informations, consultez l’interface IAsyncResult .

Remplacez cette méthode pour personnaliser le comportement des classes dérivées.

Sortie du contexte

Le exitContext paramètre n’a aucun effet, sauf si cette méthode est appelée à partir d’un contexte managé non par défaut. Le contexte managé peut être non défini par défaut si votre thread se trouve à l’intérieur d’un appel à un instance d’une classe dérivée de ContextBoundObject. Même si vous exécutez actuellement une méthode sur une classe qui n’est pas dérivée de ContextBoundObject, comme String, vous pouvez être dans un contexte non par défaut si un ContextBoundObject se trouve sur votre pile dans le domaine d’application actuel.

Lorsque votre code s’exécute dans un contexte non par défaut, la spécification true pour exitContext entraîne la sortie du thread du contexte managé non par défaut (autrement dit, pour passer au contexte par défaut) avant d’exécuter cette méthode. Le thread retourne au contexte non par défaut d’origine une fois l’appel à cette méthode terminé.

La sortie du contexte peut être utile lorsque la classe liée au contexte a l’attribut SynchronizationAttribute . Dans ce cas, tous les appels aux membres de la classe sont automatiquement synchronisés et le domaine de synchronisation est l’ensemble du corps du code de la classe. Si le code dans la pile d’appels d’un membre appelle cette méthode et spécifie true pour exitContext, le thread quitte le domaine de synchronisation, ce qui permet à un thread bloqué sur un appel à n’importe quel membre de l’objet de continuer. Lorsque cette méthode est retournée, le thread qui a effectué l’appel doit attendre d’être réentrée dans le domaine de synchronisation.

S’applique à

WaitOne(TimeSpan, Boolean)

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

Bloque le thread actuel jusqu'à ce que l'instance actuelle reçoive un signal, en utilisant une valeur TimeSpan pour spécifier l'intervalle de temps et en spécifiant s'il faut quitter le domaine de synchronisation avant l'attente.

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

Paramètres

timeout
TimeSpan

TimeSpan qui représente le nombre de millièmes de secondes à attendre ou TimeSpan qui représente -1 millième de seconde, pour attendre indéfiniment.

exitContext
Boolean

true pour quitter le domaine de synchronisation du contexte avant l'attente (dans le cas d'un contexte synchronisé) et l'acquérir à nouveau ensuite ; sinon, false.

Retours

true si l'instance actuelle reçoit un signal ; sinon, false.

Exceptions

L’instance actuelle a déjà été supprimée.

timeout est un nombre négatif différent de -1 milliseconde, qui représente un délai d’attente infini.

-ou-

timeout est supérieur à Int32.MaxValue.

L’attente s’est arrêtée, car un thread s’est terminé sans libérer de mutex.

L'instance actuelle est un proxy transparent pour un WaitHandle dans un autre domaine d'application.

Exemples

L’exemple de code suivant montre comment utiliser un handle d’attente pour empêcher un processus de se terminer pendant qu’il attend qu’un thread d’arrière-plan se termine.

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

Remarques

Si timeout est zéro, la méthode ne bloque pas. Il teste l’état du handle d’attente et retourne immédiatement.

Si un mutex est abandonné, un AbandonedMutexException est levée. Un mutex abandonné indique souvent une erreur de codage grave. Dans le cas d’un mutex à l’échelle du système, cela peut indiquer qu’une application a été arrêtée brusquement (par exemple, à l’aide du Gestionnaire des tâches Windows). L’exception contient des informations utiles pour le débogage.

L’appelant de cette méthode bloque jusqu’à ce que le instance actuel reçoive un signal ou qu’un délai d’attente se produise. Utilisez cette méthode pour bloquer jusqu’à ce qu’un WaitHandle reçoit un signal d’un autre thread, tel qu’il est généré à la fin d’une opération asynchrone. Pour plus d’informations, consultez l’interface IAsyncResult .

Remplacez cette méthode pour personnaliser le comportement des classes dérivées.

La valeur maximale pour timeout est Int32.MaxValue.

Sortie du contexte

Le exitContext paramètre n’a aucun effet, sauf si cette méthode est appelée à partir d’un contexte managé non par défaut. Le contexte managé peut être non défini par défaut si votre thread se trouve à l’intérieur d’un appel à un instance d’une classe dérivée de ContextBoundObject. Même si vous exécutez actuellement une méthode sur une classe qui n’est pas dérivée de ContextBoundObject, comme String, vous pouvez être dans un contexte non par défaut si un ContextBoundObject se trouve sur votre pile dans le domaine d’application actuel.

Lorsque votre code s’exécute dans un contexte non par défaut, la spécification true pour exitContext entraîne la sortie du thread du contexte managé non par défaut (autrement dit, pour passer au contexte par défaut) avant d’exécuter cette méthode. Le thread retourne au contexte non par défaut d’origine une fois l’appel à cette méthode terminé.

La sortie du contexte peut être utile lorsque la classe liée au contexte a l’attribut SynchronizationAttribute . Dans ce cas, tous les appels aux membres de la classe sont automatiquement synchronisés et le domaine de synchronisation est l’ensemble du corps du code de la classe. Si le code dans la pile d’appels d’un membre appelle cette méthode et spécifie true pour exitContext, le thread quitte le domaine de synchronisation, ce qui permet à un thread bloqué sur un appel à n’importe quel membre de l’objet de continuer. Lorsque cette méthode est retournée, le thread qui a effectué l’appel doit attendre d’être réentrée dans le domaine de synchronisation.

S’applique à