WaitHandle Klasse
Definition
Wichtig
Einige Informationen beziehen sich auf Vorabversionen, die vor dem Release ggf. grundlegend überarbeitet werden. Microsoft übernimmt hinsichtlich der hier bereitgestellten Informationen keine Gewährleistungen, seien sie ausdrücklich oder konkludent.
Kapselt betriebssystemspezifische Objekte, die auf exklusiven Zugriff auf gemeinsam genutzte Ressourcen warten.
public ref class WaitHandle abstract : IDisposable
public ref class WaitHandle abstract : MarshalByRefObject, IDisposable
public abstract class WaitHandle : IDisposable
public abstract class WaitHandle : MarshalByRefObject, IDisposable
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class WaitHandle : MarshalByRefObject, IDisposable
type WaitHandle = class
interface IDisposable
type WaitHandle = class
inherit MarshalByRefObject
interface IDisposable
[<System.Runtime.InteropServices.ComVisible(true)>]
type WaitHandle = class
inherit MarshalByRefObject
interface IDisposable
Public MustInherit Class WaitHandle
Implements IDisposable
Public MustInherit Class WaitHandle
Inherits MarshalByRefObject
Implements IDisposable
- Vererbung
-
WaitHandle
- Vererbung
- Abgeleitet
- Attribute
- Implementiert
Beispiele
Das folgende Codebeispiel zeigt, wie zwei Threads Hintergrundaufgaben ausführen können, während der Hauptthread mithilfe der statischen Methoden und der -Methode der -Klasse auf den Abschluss der WaitAny WaitAll Aufgaben WaitHandle wartet.
using namespace System;
using namespace System::Threading;
public ref class WaitHandleExample
{
// Define a random number generator for testing.
private:
static Random^ random = gcnew Random();
public:
static void DoTask(Object^ state)
{
AutoResetEvent^ autoReset = (AutoResetEvent^) state;
int time = 1000 * random->Next(2, 10);
Console::WriteLine("Performing a task for {0} milliseconds.", time);
Thread::Sleep(time);
autoReset->Set();
}
};
int main()
{
// Define an array with two AutoResetEvent WaitHandles.
array<WaitHandle^>^ handles = gcnew array<WaitHandle^> {
gcnew AutoResetEvent(false), gcnew AutoResetEvent(false)};
// Queue up two tasks on two different threads;
// wait until all tasks are completed.
DateTime timeInstance = DateTime::Now;
Console::WriteLine("Main thread is waiting for BOTH tasks to " +
"complete.");
ThreadPool::QueueUserWorkItem(
gcnew WaitCallback(WaitHandleExample::DoTask), handles[0]);
ThreadPool::QueueUserWorkItem(
gcnew WaitCallback(WaitHandleExample::DoTask), handles[1]);
WaitHandle::WaitAll(handles);
// The time shown below should match the longest task.
Console::WriteLine("Both tasks are completed (time waited={0})",
(DateTime::Now - timeInstance).TotalMilliseconds);
// Queue up two tasks on two different threads;
// wait until any tasks are completed.
timeInstance = DateTime::Now;
Console::WriteLine();
Console::WriteLine("The main thread is waiting for either task to " +
"complete.");
ThreadPool::QueueUserWorkItem(
gcnew WaitCallback(WaitHandleExample::DoTask), handles[0]);
ThreadPool::QueueUserWorkItem(
gcnew WaitCallback(WaitHandleExample::DoTask), handles[1]);
int index = WaitHandle::WaitAny(handles);
// The time shown below should match the shortest task.
Console::WriteLine("Task {0} finished first (time waited={1}).",
index + 1, (DateTime::Now - timeInstance).TotalMilliseconds);
}
// This code produces the following sample output.
//
// Main thread is waiting for BOTH tasks to complete.
// Performing a task for 7000 milliseconds.
// Performing a task for 4000 milliseconds.
// Both tasks are completed (time waited=7064.8052)
// The main thread is waiting for either task to complete.
// Performing a task for 2000 milliseconds.
// Performing a task for 2000 milliseconds.
// Task 1 finished first (time waited=2000.6528).
using System;
using System.Threading;
public sealed class App
{
// Define an array with two AutoResetEvent WaitHandles.
static WaitHandle[] waitHandles = new WaitHandle[]
{
new AutoResetEvent(false),
new AutoResetEvent(false)
};
// Define a random number generator for testing.
static Random r = new Random();
static void Main()
{
// Queue up two tasks on two different threads;
// wait until all tasks are completed.
DateTime dt = DateTime.Now;
Console.WriteLine("Main thread is waiting for BOTH tasks to complete.");
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]);
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]);
WaitHandle.WaitAll(waitHandles);
// The time shown below should match the longest task.
Console.WriteLine("Both tasks are completed (time waited={0})",
(DateTime.Now - dt).TotalMilliseconds);
// Queue up two tasks on two different threads;
// wait until any tasks are completed.
dt = DateTime.Now;
Console.WriteLine();
Console.WriteLine("The main thread is waiting for either task to complete.");
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]);
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]);
int index = WaitHandle.WaitAny(waitHandles);
// The time shown below should match the shortest task.
Console.WriteLine("Task {0} finished first (time waited={1}).",
index + 1, (DateTime.Now - dt).TotalMilliseconds);
}
static void DoTask(Object state)
{
AutoResetEvent are = (AutoResetEvent) state;
int time = 1000 * r.Next(2, 10);
Console.WriteLine("Performing a task for {0} milliseconds.", time);
Thread.Sleep(time);
are.Set();
}
}
// This code produces output similar to the following:
//
// Main thread is waiting for BOTH tasks to complete.
// Performing a task for 7000 milliseconds.
// Performing a task for 4000 milliseconds.
// Both tasks are completed (time waited=7064.8052)
//
// The main thread is waiting for either task to complete.
// Performing a task for 2000 milliseconds.
// Performing a task for 2000 milliseconds.
// Task 1 finished first (time waited=2000.6528).
Imports System.Threading
NotInheritable Public Class App
' Define an array with two AutoResetEvent WaitHandles.
Private Shared waitHandles() As WaitHandle = _
{New AutoResetEvent(False), New AutoResetEvent(False)}
' Define a random number generator for testing.
Private Shared r As New Random()
<MTAThreadAttribute> _
Public Shared Sub Main()
' Queue two tasks on two different threads;
' wait until all tasks are completed.
Dim dt As DateTime = DateTime.Now
Console.WriteLine("Main thread is waiting for BOTH tasks to complete.")
ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(0))
ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(1))
WaitHandle.WaitAll(waitHandles)
' The time shown below should match the longest task.
Console.WriteLine("Both tasks are completed (time waited={0})", _
(DateTime.Now - dt).TotalMilliseconds)
' Queue up two tasks on two different threads;
' wait until any tasks are completed.
dt = DateTime.Now
Console.WriteLine()
Console.WriteLine("The main thread is waiting for either task to complete.")
ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(0))
ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(1))
Dim index As Integer = WaitHandle.WaitAny(waitHandles)
' The time shown below should match the shortest task.
Console.WriteLine("Task {0} finished first (time waited={1}).", _
index + 1,(DateTime.Now - dt).TotalMilliseconds)
End Sub
Shared Sub DoTask(ByVal state As [Object])
Dim are As AutoResetEvent = CType(state, AutoResetEvent)
Dim time As Integer = 1000 * r.Next(2, 10)
Console.WriteLine("Performing a task for {0} milliseconds.", time)
Thread.Sleep(time)
are.Set()
End Sub
End Class
' This code produces output similar to the following:
'
' Main thread is waiting for BOTH tasks to complete.
' Performing a task for 7000 milliseconds.
' Performing a task for 4000 milliseconds.
' Both tasks are completed (time waited=7064.8052)
'
' The main thread is waiting for either task to complete.
' Performing a task for 2000 milliseconds.
' Performing a task for 2000 milliseconds.
' Task 1 finished first (time waited=2000.6528).
Hinweise
Die WaitHandle -Klasse kapselt ein systemeigenes Synchronisierungshandler des Betriebssystems und wird verwendet, um alle Synchronisierungsobjekte in der Laufzeit zu darstellen, die mehrere Wartevorgänge zulassen. Einen Vergleich von Wait-Handles mit anderen Synchronisierungsobjekten finden Sie unter Übersicht über Synchronisierungsprimitiven.
Die WaitHandle Klasse selbst ist abstrakt. Klassen, die von abgeleitet werden, definieren einen Signalisierungsmechanismus, um anzugeben, dass der Zugriff auf eine freigegebene Ressource übernommen oder freigegeben wird. Sie verwenden jedoch die geerbten Methoden, um zu blockieren, während auf den Zugriff auf freigegebene WaitHandle WaitHandle Ressourcen gewartet wird. Folgende Klassen werden von WaitHandle abgeleitet:
Die Mutex-Klasse. Weitere Informationen finden Sie unter Mutexe.
Die EventWaitHandle -Klasse und die abgeleiteten Klassen AutoResetEvent und ManualResetEvent .
Die Semaphore-Klasse. Weitere Informationen finden Sie unter Semaphore und SemaphoreSlim.
Threads können auf einem einzelnen Wait-Handle blockieren, indem sie die Instanzmethode aufrufen, die von von WaitOne abgeleiteten Klassen geerbt WaitHandle wird.
Die abgeleiteten Klassen WaitHandle von unterscheiden sich in ihrer Threadaffinität. Ereigniswartehandles ( , und ) und Semaphore haben keine Threadaffinität. Jeder Thread kann ein Ereigniswartehandles oder EventWaitHandle AutoResetEvent ManualResetEvent Semaphor signalisieren. Mutexe hingegen verfügen über Threadaffinität. Der Thread, der einen Mutex besitzt, muss ihn frei geben, und es wird eine Ausnahme ausgelöst, wenn ein Thread die -Methode für einen Mutex aufruft, der nicht im Eigenen ReleaseMutex ist.
Da die -Klasse von ableitung, können diese Klassen verwendet werden, um die Aktivitäten von Threads über WaitHandle MarshalByRefObject Anwendungsdomänengrenzen hinweg zu synchronisieren.
Zusätzlich zu den abgeleiteten Klassen verfügt die -Klasse über eine Reihe statischer Methoden, die einen Thread blockieren, bis ein oder mehrere Synchronisierungsobjekte WaitHandle ein Signal empfangen. Dazu gehören:
SignalAndWait, wodurch ein Thread ein Wartehand handle signalisieren und sofort auf ein anderes warten kann.
WaitAll, wodurch ein Thread warten kann, bis alle Wait-Handles in einem Array ein Signal empfangen.
WaitAny, wodurch ein Thread warten kann, bis eines der angegebenen Wartehandles signalisiert wurde.
Die Überladungen dieser Methoden bieten Timeoutintervalle für den Abbruch des Warteintervalls und die Möglichkeit, einen Synchronisierungskontext vor dem Eintritt in den Wartekontext zu beenden, sodass andere Threads den Synchronisierungskontext verwenden können.
Wichtig
Dieser Typ implementiert die IDisposable-Schnittstelle. Wenn Sie den Typ oder einen davon abgeleiteten Typ nicht mehr verwenden, sollten Sie ihn entweder direkt oder indirekt veräußern. Zum direkten Löschen des Typs rufen Sie seine Close-Methode in einem try/catch-Block auf. Zum indirekten Löschen verwenden Sie ein Sprachkonstrukt wie using (in C#) oder Using (in Visual Basic). Weitere Informationen finden Sie im Abschnitt „Verwenden eines Objekts, das IDisposable implementiert“ des Themas „Die IDisposable-Schnittstelle“.
WaitHandle implementiert das Dispose -Muster. Weitere Informationen finden Sie unter Implementieren einer Dispose-Methode. Wenn Sie von WaitHandle ableiten, verwenden Sie die SafeWaitHandle -Eigenschaft, um ihr systemeigenes Betriebssystemhand handle zu speichern. Sie müssen die geschützte Methode nur Dispose überschreiben, wenn Sie zusätzliche nicht verwaltete Ressourcen verwenden.
Konstruktoren
| WaitHandle() |
Initialisiert eine neue Instanz der WaitHandle-Klasse. |
Felder
| InvalidHandle |
Stellt ein ungültiges systemeigenes Betriebssystemhandle dar. Dieses Feld ist schreibgeschützt. |
| WaitTimeout |
Gibt an, dass ein Timeout für einen WaitAny(WaitHandle[], Int32, Boolean)-Vorgang überschritten wurde, bevor ein Signal an eines der WaitHandles gesendet wurde. Dieses Feld ist konstant. |
Eigenschaften
| Handle |
Veraltet.
Veraltet.
Ruft das systemeigene Betriebssystemhandle auf oder legt dieses fest. |
| SafeWaitHandle |
Ruft das systemeigene Betriebssystemhandle auf oder legt dieses fest. |
Methoden
| Close() |
Gibt alle von der aktuellen WaitHandle-Klasse reservierten Ressourcen frei. |
| CreateObjRef(Type) |
Erstellt ein Objekt mit allen relevanten Informationen, die zum Generieren eines Proxys für die Kommunikation mit einem Remoteobjekt erforderlich sind. (Geerbt von MarshalByRefObject) |
| Dispose() |
Gibt alle von der aktuellen Instanz der WaitHandle-Klasse verwendeten Ressourcen frei. |
| Dispose(Boolean) |
Gibt beim Überschreiben in einer abgeleiteten Klasse die von WaitHandle verwendeten nicht verwalteten Ressourcen und optional die verwalteten Ressourcen frei. |
| Equals(Object) |
Bestimmt, ob das angegebene Objekt gleich dem aktuellen Objekt ist. (Geerbt von Object) |
| Finalize() |
Gibt die von der aktuellen Instanz reservierten Ressourcen frei. |
| GetHashCode() |
Fungiert als Standardhashfunktion. (Geerbt von Object) |
| GetLifetimeService() |
Veraltet.
Ruft das aktuelle Lebensdauerdienstobjekt ab, das die Lebensdauerrichtlinien für diese Instanz steuert. (Geerbt von MarshalByRefObject) |
| GetType() |
Ruft den Type der aktuellen Instanz ab. (Geerbt von Object) |
| InitializeLifetimeService() |
Veraltet.
Ruft ein Lebensdauerdienstobjekt zur Steuerung der Lebensdauerrichtlinie für diese Instanz ab. (Geerbt von MarshalByRefObject) |
| MemberwiseClone() |
Erstellt eine flache Kopie des aktuellen Object. (Geerbt von Object) |
| MemberwiseClone(Boolean) |
Erstellt eine flache Kopie des aktuellen MarshalByRefObject-Objekts. (Geerbt von MarshalByRefObject) |
| SignalAndWait(WaitHandle, WaitHandle) |
Signalisiert ein WaitHandle und wartet auf einen anderen. |
| SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean) |
Signalisiert ein WaitHandle und wartet auf ein weiteres, wobei ein Timeoutintervall als 32-Bit-Ganzzahl mit Vorzeichen angegeben und festgelegt wird, ob die Synchronisierungsdomäne des Kontexts vor dem Wartevorgang verlassen werden soll. |
| SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean) |
Signalisiert ein WaitHandle und wartet auf ein weiteres, wobei das Timeoutintervall als TimeSpan angegeben und festgelegt wird, ob die Synchronisierungsdomäne des Kontexts vor dem Wartevorgang verlassen werden soll. |
| ToString() |
Gibt eine Zeichenfolge zurück, die das aktuelle Objekt darstellt. (Geerbt von Object) |
| WaitAll(WaitHandle[]) |
Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen. |
| WaitAll(WaitHandle[], Int32) |
Wartet auf den Empfang eines Signals für alle Elemente im angegebenen Array und gibt das Zeitintervall mit einem Int32-Wert an. |
| WaitAll(WaitHandle[], Int32, Boolean) |
Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen, wobei ein Int32-Wert zum Angeben des Zeitintervalls verwendet wird, und gibt an, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll. |
| WaitAll(WaitHandle[], TimeSpan) |
Wartet auf den Empfang eines Signals für alle Elemente im angegebenen Array und gibt das Zeitintervall mit einem TimeSpan-Wert an. |
| WaitAll(WaitHandle[], TimeSpan, Boolean) |
Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen, wobei ein TimeSpan-Wert zum Angeben des Zeitintervalls verwendet wird, und gibt an, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll. |
| WaitAny(WaitHandle[]) |
Wartet, bis Elemente im angegebenen Array ein Signal empfangen. |
| WaitAny(WaitHandle[], Int32) |
Wartet auf den Empfang eines Signals für alle Elemente im angegebenen Array und gibt das Zeitintervall mit einer 32-Bit-Ganzzahl mit Vorzeichen an. |
| WaitAny(WaitHandle[], Int32, Boolean) |
Wartet, bis Elemente im angegebenen Array ein Signal empfangen, wobei eine 32-Bit-Ganzzahl mit Vorzeichen zum Angeben des Zeitintervalls verwendet wird, und gibt an, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll. |
| WaitAny(WaitHandle[], TimeSpan) |
Wartet auf den Empfang eines Signals für alle Elemente im angegebenen Array und gibt das Zeitintervall mit einem TimeSpan-Wert an. |
| WaitAny(WaitHandle[], TimeSpan, Boolean) |
Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen, wobei ein TimeSpan zum Angeben des Zeitintervalls verwendet wird, und gibt an, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll. |
| WaitOne() |
Blockiert den aktuellen Thread, bis das aktuelle WaitHandle ein Signal empfängt. |
| WaitOne(Int32) |
Blockiert den aktuellen Thread, bis das aktuelle WaitHandle ein Signal empfängt, wobei eine 32-Bit-Ganzzahl mit Vorzeichen zum Angeben des Zeitintervalls in Millisekunden verwendet wird. |
| WaitOne(Int32, Boolean) |
Blockiert den aktuellen Thread, bis das aktuelle WaitHandle ein Signal empfängt, wobei eine 32-Bit-Ganzzahl mit Vorzeichen zum Angeben des Zeitintervalls verwendet und angegeben wird, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll. |
| WaitOne(TimeSpan) |
Blockiert den aktuellen Thread, bis die aktuelle Instanz ein Signal empfängt, wobei eine TimeSpan zum Angeben des Zeitintervalls verwendet wird. |
| WaitOne(TimeSpan, Boolean) |
Blockiert den aktuellen Thread, bis die aktuelle Instanz ein Signal empfängt, wobei eine TimeSpan zum Angeben des Zeitintervalls verwendet und angegeben wird, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll. |
Explizite Schnittstellenimplementierungen
| IDisposable.Dispose() |
Diese API unterstützt die Produktinfrastruktur und ist nicht für die direkte Verwendung aus Ihrem Code gedacht. Gibt alle vom WaitHandle verwendeten Ressourcen frei. |
Erweiterungsmethoden
| GetSafeWaitHandle(WaitHandle) |
Ruft das sichere Handle für ein systemeigenes Betriebssystem-Wait-Handle ab. |
| SetSafeWaitHandle(WaitHandle, SafeWaitHandle) |
Stellt ein sicheres Handle für ein systemeigenes Betriebssystem-Wait-Handle ein. |
Gilt für:
Threadsicherheit
Dieser Typ ist threadsicher.