WaitHandle.WaitOne Méthode
Définition
Important
Certaines informations portent sur la préversion du produit qui est susceptible d’être en grande partie modifiée avant sa publication. Microsoft exclut toute garantie, expresse ou implicite, concernant les informations fournies ici.
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.