WaitHandle.WaitOne Metodo
Definizione
Importante
Alcune informazioni sono relative alla release non definitiva del prodotto, che potrebbe subire modifiche significative prima della release definitiva. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale.
Overload
WaitOne() |
Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale. |
WaitOne(Int32) |
Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale, usando un intero con segno a 32 bit per specificare l'intervallo di tempo. |
WaitOne(TimeSpan) |
Blocca il thread corrente finché l'istanza corrente non riceve un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo. |
WaitOne(Int32, Boolean) |
Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale, usando un intero con segno a 32 bit per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa. |
WaitOne(TimeSpan, Boolean) |
Blocca il thread corrente finché l'istanza corrente non riceve un segnale, usando un oggetto TimeSpan per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa. |
WaitOne()
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale.
public:
virtual bool WaitOne();
public virtual bool WaitOne ();
abstract member WaitOne : unit -> bool
override this.WaitOne : unit -> bool
Public Overridable Function WaitOne () As Boolean
Restituisce
Viene restituito true
se l'istanza corrente riceve un segnale. Se l'istanza corrente non viene mai segnalata, WaitOne() non restituisce mai alcun valore.
Eccezioni
L'istanza corrente è già stata eliminata.
L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.
L'istanza corrente corrisponde a un proxy trasparente per una classe WaitHandle in un altro dominio applicazione.
Esempio
Nell'esempio di codice seguente viene illustrato come usare un handle di attesa per impedire a un processo di terminazione mentre attende che un thread in background finisca l'esecuzione.
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
Commenti
AbandonedMutexException è nuovo in .NET Framework versione 2.0. Nelle versioni precedenti, il WaitOne metodo restituisce true
quando viene abbandonato un mutex. Un mutex abbandonato spesso indica un grave errore di codifica. Nel caso di un mutex a livello di sistema, potrebbe indicare che un'applicazione è stata terminata bruscamente (ad esempio usando Gestione attività di Windows). L'eccezione contiene informazioni utili per il debug.
Il chiamante di questo metodo blocca indefinito fino a quando l'istanza corrente riceve un segnale. Usare questo metodo per bloccare finché un WaitHandle segnale non riceve un segnale da un altro thread, ad esempio viene generato al termine di un'operazione asincrona. Per altre informazioni, vedere l'interfaccia IAsyncResult .
La chiamata all'overload di questo metodo equivale a chiamare l'overload del WaitOne(Int32, Boolean) metodo e specificare -1 o Timeout.Infinite per il primo parametro e false
per il secondo parametro.
Eseguire l'override di questo metodo per personalizzare il comportamento delle classi derivate.
Si applica a
WaitOne(Int32)
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale, usando un intero con segno a 32 bit per specificare l'intervallo di tempo.
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
Parametri
- millisecondsTimeout
- Int32
Numero di millisecondi di attesa oppure Infinite (-1) per un'attesa indefinita.
Restituisce
true
se l'istanza corrente riceve un segnale; in caso contrario false
.
Eccezioni
L'istanza corrente è già stata eliminata.
millisecondsTimeout
è un numero negativo diverso da -1, che rappresenta un timeout infinito.
L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.
L'istanza corrente corrisponde a un proxy trasparente per una classe WaitHandle in un altro dominio applicazione.
Esempio
Nell'esempio di codice seguente viene illustrato come usare un handle di attesa per impedire a un processo di terminazione mentre attende che un thread in background finisca l'esecuzione.
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
Commenti
Se millisecondsTimeout
è zero, il metodo non blocca. Verifica lo stato dell'handle di attesa e restituisce immediatamente.
Il chiamante di questo metodo blocca fino a quando l'istanza corrente riceve un segnale o un timeout. Usare questo metodo per bloccare finché un WaitHandle segnale non riceve un segnale da un altro thread, ad esempio viene generato al termine di un'operazione asincrona. Per altre informazioni, vedere l'interfaccia IAsyncResult .
Eseguire l'override di questo metodo per personalizzare il comportamento delle classi derivate.
La chiamata all'overload di questo metodo è uguale a quella di chiamare l'overload WaitOne(Int32, Boolean) e specificare false
per exitContext
.
Si applica a
WaitOne(TimeSpan)
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
Blocca il thread corrente finché l'istanza corrente non riceve un segnale, usando un valore TimeSpan per specificare l'intervallo di 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
Parametri
- timeout
- TimeSpan
Oggetto TimeSpan che rappresenta il numero di millisecondi di attesa oppure TimeSpan che rappresenta -1 millisecondi per un'attesa indefinita.
Restituisce
true
se l'istanza corrente riceve un segnale; in caso contrario false
.
Eccezioni
L'istanza corrente è già stata eliminata.
timeout
è un numero negativo diverso da -1 millisecondi, che rappresenta un timeout infinito.
-oppure-
timeout
è maggiore di Int32.MaxValue.
L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.
L'istanza corrente corrisponde a un proxy trasparente per una classe WaitHandle in un altro dominio applicazione.
Commenti
Se timeout
è zero, il metodo non blocca. Verifica lo stato dell'handle di attesa e restituisce immediatamente.
Il chiamante di questo metodo blocca fino a quando l'istanza corrente riceve un segnale o un timeout. Usare questo metodo per bloccare finché un WaitHandle segnale non riceve un segnale da un altro thread, ad esempio viene generato al termine di un'operazione asincrona. Per altre informazioni, vedere l'interfaccia IAsyncResult .
Eseguire l'override di questo metodo per personalizzare il comportamento delle classi derivate.
Il valore massimo per timeout
è Int32.MaxValue.
La chiamata all'overload di questo metodo è uguale a quella di chiamare l'overload WaitOne(TimeSpan, Boolean) e specificare false
per exitContext
.
Si applica a
WaitOne(Int32, Boolean)
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale, usando un intero con segno a 32 bit per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.
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
Parametri
- millisecondsTimeout
- Int32
Numero di millisecondi di attesa oppure Infinite (-1) per un'attesa indefinita.
- exitContext
- Boolean
true
per uscire dal dominio di sincronizzazione per il contesto prima dell'attesa, se all'interno di un contesto sincronizzato, e riacquisirlo successivamente; in caso contrario, false
.
Restituisce
true
se l'istanza corrente riceve un segnale; in caso contrario false
.
Eccezioni
L'istanza corrente è già stata eliminata.
millisecondsTimeout
è un numero negativo diverso da -1, che rappresenta un timeout infinito.
L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.
L'istanza corrente corrisponde a un proxy trasparente per una classe WaitHandle in un altro dominio applicazione.
Esempio
Nell'esempio seguente viene illustrato il comportamento dell'overload del WaitOne(Int32, Boolean) metodo quando viene chiamato all'interno di un dominio di sincronizzazione. Prima di tutto, un thread attende con exitContext
impostato su false
e blocca fino alla scadenza del timeout di attesa. Un secondo thread viene eseguito dopo che il primo thread termina e attende con exitContext
impostato su true
. La chiamata per segnalare l'handle di attesa per questo secondo thread non è bloccata e il thread viene completato prima del timeout di attesa.
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!!!
Commenti
Se millisecondsTimeout
è zero, il metodo non blocca. Verifica lo stato dell'handle di attesa e restituisce immediatamente.
Se viene abbandonato un mutex, viene generato un AbandonedMutexException oggetto. Un mutex abbandonato spesso indica un grave errore di codifica. Nel caso di un mutex a livello di sistema, potrebbe indicare che un'applicazione è stata terminata bruscamente (ad esempio usando Gestione attività di Windows). L'eccezione contiene informazioni utili per il debug.
Il chiamante di questo metodo blocca fino a quando l'istanza corrente riceve un segnale o un timeout. Usare questo metodo per bloccare finché un WaitHandle segnale non riceve un segnale da un altro thread, ad esempio viene generato al termine di un'operazione asincrona. Per altre informazioni, vedere l'interfaccia IAsyncResult .
Eseguire l'override di questo metodo per personalizzare il comportamento delle classi derivate.
Uscita dal contesto
Il exitContext
parametro non ha alcun effetto a meno che questo metodo non venga chiamato dall'interno di un contesto gestito non definito. Il contesto gestito può essere non definito se il thread si trova all'interno di una chiamata a un'istanza di una classe derivata da ContextBoundObject. Anche se si sta eseguendo un metodo in una classe che non è derivata da ContextBoundObject, ad esempio String, è possibile essere in un contesto non definito se un ContextBoundObject è nello stack nel dominio dell'applicazione corrente.
Quando il codice viene eseguito in un contesto non definito, specificando true
per exitContext
causare l'uscita del thread dal contesto gestito non definito, ovvero per passare al contesto predefinito, prima di eseguire questo metodo. Il thread torna al contesto non definito originale dopo il completamento della chiamata a questo metodo.
L'uscita dal contesto può essere utile quando la classe associata al contesto ha l'attributo SynchronizationAttribute . In tal caso, tutte le chiamate ai membri della classe vengono sincronizzate automaticamente e il dominio di sincronizzazione è l'intero corpo del codice per la classe. Se il codice nello stack di chiamate di un membro chiama questo metodo e specifica true
per exitContext
, il thread chiude il dominio di sincronizzazione, che consente a un thread bloccato su una chiamata a qualsiasi membro dell'oggetto di procedere. Quando questo metodo restituisce, il thread che ha effettuato la chiamata deve attendere di tornare al dominio di sincronizzazione.
Si applica a
WaitOne(TimeSpan, Boolean)
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
- Origine:
- WaitHandle.cs
Blocca il thread corrente finché l'istanza corrente non riceve un segnale, usando un oggetto TimeSpan per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.
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
Parametri
- timeout
- TimeSpan
Oggetto TimeSpan che rappresenta il numero di millisecondi di attesa oppure TimeSpan che rappresenta -1 millisecondi per un'attesa indefinita.
- exitContext
- Boolean
true
per uscire dal dominio di sincronizzazione per il contesto prima dell'attesa, se all'interno di un contesto sincronizzato, e riacquisirlo successivamente; in caso contrario, false
.
Restituisce
true
se l'istanza corrente riceve un segnale; in caso contrario false
.
Eccezioni
L'istanza corrente è già stata eliminata.
timeout
è un numero negativo diverso da -1 millisecondi, che rappresenta un timeout infinito.
-oppure-
timeout
è maggiore di Int32.MaxValue.
L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.
L'istanza corrente corrisponde a un proxy trasparente per una classe WaitHandle in un altro dominio applicazione.
Esempio
Nell'esempio di codice seguente viene illustrato come usare un handle di attesa per impedire a un processo di terminazione mentre attende che un thread in background finisca l'esecuzione.
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
Commenti
Se timeout
è zero, il metodo non viene bloccato. Verifica lo stato dell'handle di attesa e restituisce immediatamente.
Se un mutex viene abbandonato, viene generata un'eccezione AbandonedMutexException . Un mutex abbandonato spesso indica un errore di codifica grave. Nel caso di un mutex a livello di sistema, potrebbe indicare che un'applicazione è stata terminata bruscamente ,ad esempio tramite Gestione attività di Windows. L'eccezione contiene informazioni utili per il debug.
Il chiamante di questo metodo si blocca finché l'istanza corrente non riceve un segnale o si verifica un timeout. Usare questo metodo per bloccare finché un oggetto WaitHandle non riceve un segnale da un altro thread, ad esempio quando viene completata un'operazione asincrona. Per altre informazioni, vedere l'interfaccia IAsyncResult .
Eseguire l'override di questo metodo per personalizzare il comportamento delle classi derivate.
Il valore massimo per timeout
è Int32.MaxValue.
Uscita dal contesto
Il exitContext
parametro non ha alcun effetto a meno che questo metodo non venga chiamato dall'interno di un contesto gestito non predefinito. Il contesto gestito può essere non predefinito se il thread si trova all'interno di una chiamata a un'istanza di una classe derivata da ContextBoundObject. Anche se attualmente si esegue un metodo in una classe che non è derivata da ContextBoundObject, ad esempio String, è possibile trovarsi in un contesto non predefinito se un ContextBoundObject oggetto si trova nello stack nel dominio applicazione corrente.
Quando il codice viene eseguito in un contesto non predefinito, se true
si specifica per exitContext
fa in modo che il thread esce dal contesto gestito non predefinito, ovvero per passare al contesto predefinito, prima di eseguire questo metodo. Il thread torna al contesto non predefinito originale al termine della chiamata a questo metodo.
L'uscita dal contesto può essere utile quando la classe associata al contesto ha l'attributo SynchronizationAttribute . In tal caso, tutte le chiamate ai membri della classe vengono sincronizzate automaticamente e il dominio di sincronizzazione è l'intero corpo del codice per la classe . Se il codice nello stack di chiamate di un membro chiama questo metodo e specifica true
per exitContext
, il thread esce dal dominio di sincronizzazione, che consente a un thread bloccato in una chiamata a qualsiasi membro dell'oggetto di continuare. Quando termina, il thread che ha eseguito la chiamata deve attendere di immettere nuovamente il dominio di sincronizzazione.