Sdílet prostřednictvím


WaitHandle Třída

Definice

Zapouzdří objekty specifické pro operační systém, které čekají na výhradní přístup ke sdíleným prostředkům.

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
Dědičnost
WaitHandle
Dědičnost
Odvozené
Atributy
Implementuje

Příklady

Následující příklad kódu ukazuje, jak dvě vlákna mohou provádět úlohy na pozadí, zatímco hlavní vlákno čeká na dokončení úkolů pomocí statické WaitAny a WaitAll metody WaitHandle třídy.

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 task is 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).

Poznámky

Třída WaitHandle zapouzdřuje nativní popisovač synchronizace operačního systému a slouží k reprezentaci všech synchronizačních objektů v modulu runtime, které umožňují více operací čekání. Porovnání popisovačů čekání s jinými synchronizačními objekty najdete v tématu Přehled primitiv synchronizace.

Samotná WaitHandle třída je abstraktní. Třídy odvozené z WaitHandle definice signalizačního mechanismu označující převzetí nebo uvolnění přístupu ke sdílenému prostředku, ale při čekání na přístup ke sdíleným prostředkům používají zděděné WaitHandle metody k blokování. Mezi třídy odvozené z WaitHandle patří:

Vlákna mohou blokovat na jednotlivém popisovači čekání voláním metody WaitOneinstance , která je zděděna třídami odvozenými z WaitHandle.

Odvozené třídy se WaitHandle liší v jejich spřažení vlákna. Obslužné rutiny čekání událostí (EventWaitHandle, AutoResetEventa ManualResetEvent) a semafory nemají spřažení vlákna. Jakékoli vlákno může signalizovat popisovač čekání na událost nebo semafor. Mutexy, na druhé straně, mají spřažení vláken; vlákno, které vlastní mutex, ho musí uvolnit a vyvolá výjimku, pokud vlákno volá metodu ReleaseMutex na mutexu, který nevlastní.

Vzhledem k tomu, že WaitHandle třída je odvozena z MarshalByRefObject, lze tyto třídy použít k synchronizaci aktivit vláken napříč hranicemi domény aplikace.

Kromě odvozených tříd WaitHandle má třída řadu statických metod, které blokují vlákno, dokud jeden nebo více synchronizačních objektů neobdrží signál. Tady jsou některé z nich:

  • SignalAndWait, který umožňuje vláknu signalizovat jeden popisovač čekání a okamžitě čekat na jiný.

  • WaitAll, což umožňuje vláknu počkat, dokud všechny obslužné rutiny čekání v poli neobdrží signál.

  • WaitAny, což umožňuje vláknu počkat, dokud nebude signalizována některá ze zadaných sad obslužných rutin čekání.

Přetížení těchto metod poskytují intervaly časového limitu pro opuštění čekání a možnost ukončit kontext synchronizace před zadáním čekání, což umožňuje jiným vláknům používat kontext synchronizace.

Důležité

Tento typ implementuje IDisposable rozhraní. Jakmile dokončíte používání typu nebo z něj odvozeného typu, měli byste je přímo nebo nepřímo odstranit. Pokud chcete odstranit typ přímo, zavolejte jeho Close metodu try/catch v bloku. Pokud ho chcete odstranit nepřímo, použijte konstruktor jazyka, například using (v jazyce C#) nebo Using (v jazyce Visual Basic). Další informace najdete v části "Použití objektu, který implementuje IDisposable" v IDisposable tématu rozhraní.

WaitHandle implementuje Dispose vzor. Viz Implementace metody Dispose. Při odvození z WaitHandlepoužijte SafeWaitHandle vlastnost k uložení popisovače nativního operačního systému. Pokud nepoužíváte další nespravované prostředky, nemusíte přepsat chráněnou Dispose metodu.

Konstruktory

WaitHandle()

Inicializuje novou instanci WaitHandle třídy.

Pole

InvalidHandle

Představuje neplatný popisovač nativního operačního systému. Toto pole je jen ke čtení.

WaitTimeout

Označuje, že WaitAny(WaitHandle[], Int32, Boolean) časový limit operace vypršel před signálem některého z popisovačů čekání. Toto pole je konstantní.

Vlastnosti

Handle
Zastaralé.
Zastaralé.

Získá nebo nastaví popisovač nativního operačního systému.

SafeWaitHandle

Získá nebo nastaví popisovač nativního operačního systému.

Metody

Close()

Uvolní všechny prostředky, které má aktuální WaitHandle.

CreateObjRef(Type)

Vytvoří objekt, který obsahuje všechny relevantní informace potřebné k vygenerování proxy používaného ke komunikaci se vzdáleným objektem.

(Zděděno od MarshalByRefObject)
Dispose()

Uvolní všechny prostředky používané aktuální instancí WaitHandle třídy.

Dispose(Boolean)

Při přepsání v odvozené třídě uvolní nespravované prostředky používané WaitHandlenástrojem a volitelně uvolní spravované prostředky.

Equals(Object)

Určí, zda se zadaný objekt rovná aktuálnímu objektu.

(Zděděno od Object)
Finalize()

Uvolní prostředky držené aktuální instancí.

GetHashCode()

Slouží jako výchozí hashovací funkce.

(Zděděno od Object)
GetLifetimeService()
Zastaralé.

Načte objekt služby aktuální životnosti, který řídí zásady životnosti pro tuto instanci.

(Zděděno od MarshalByRefObject)
GetType()

Získá aktuální Type instanci.

(Zděděno od Object)
InitializeLifetimeService()
Zastaralé.

Získá objekt služby životnosti, který řídí zásady životnosti pro tuto instanci.

(Zděděno od MarshalByRefObject)
MemberwiseClone()

Vytvoří mělkou kopii aktuálního Objectsouboru .

(Zděděno od Object)
MemberwiseClone(Boolean)

Vytvoří mělkou kopii aktuálního MarshalByRefObject objektu.

(Zděděno od MarshalByRefObject)
SignalAndWait(WaitHandle, WaitHandle)

Signalizuje jeden WaitHandle a čeká na druhého.

SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean)

Signalizuje jednu WaitHandle a počká na druhou, určuje interval časového limitu jako 32bitové celé číslo se znaménkem a určuje, zda se má před zadáním čekání ukončit doména synchronizace pro kontext.

SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)

Signalizuje jeden WaitHandle a čeká na druhý, určuje časový limit intervalu jako TimeSpan a určuje, jestli se má před zadáním čekání ukončit synchronizační doména pro kontext.

ToString()

Vrátí řetězec, který představuje aktuální objekt.

(Zděděno od Object)
WaitAll(WaitHandle[])

Čeká na přijetí signálu všemi prvky v zadaném poli.

WaitAll(WaitHandle[], Int32)

Čeká na přijetí signálu všemi prvky v zadaném poli pomocí Int32 hodnoty pro určení časového intervalu.

WaitAll(WaitHandle[], Int32, Boolean)

Čeká, až všechny prvky v zadaném poli obdrží signál, pomocí Int32 hodnoty pro určení časového intervalu a určení, zda se má před čekáním ukončit synchronizační doména.

WaitAll(WaitHandle[], TimeSpan)

Čeká na přijetí signálu všemi prvky v zadaném poli pomocí TimeSpan hodnoty pro určení časového intervalu.

WaitAll(WaitHandle[], TimeSpan, Boolean)

Čeká, až všechny prvky v zadaném poli obdrží signál, pomocí TimeSpan hodnoty pro určení časového intervalu a určení, zda se má doména synchronizace ukončit před čekáním.

WaitAny(WaitHandle[])

Čeká na přijetí signálu některým z prvků v zadaném poli.

WaitAny(WaitHandle[], Int32)

Čeká, až některý z prvků v zadaném poli přijme signál, pomocí 32bitového celého čísla se znaménkem určí časový interval.

WaitAny(WaitHandle[], Int32, Boolean)

Čeká, až některý z prvků v zadaném poli přijme signál, pomocí 32bitového celého čísla se znaménkem určí časový interval a určí, zda se má před čekáním ukončit synchronizační doména.

WaitAny(WaitHandle[], TimeSpan)

Čeká, až některý z prvků v zadaném poli přijme signál, pomocí parametru TimeSpan pro určení časového intervalu.

WaitAny(WaitHandle[], TimeSpan, Boolean)

Čeká, až některý z prvků v zadaném poli přijme signál, pomocí parametru TimeSpan pro určení časového intervalu a určení, zda se má před čekáním ukončit synchronizační doména.

WaitOne()

Blokuje aktuální vlákno, dokud proud WaitHandle neobdrží signál.

WaitOne(Int32)

Blokuje aktuální vlákno, dokud proud WaitHandle neobdrží signál, pomocí 32bitového celého čísla se znaménkem určuje časový interval v milisekundách.

WaitOne(Int32, Boolean)

Blokuje aktuální vlákno, dokud proud WaitHandle neobdrží signál. Pomocí 32bitového celého čísla se znaménkem určuje časový interval a určuje, jestli se má před čekáním ukončit synchronizační doména.

WaitOne(TimeSpan)

Blokuje aktuální vlákno, dokud aktuální instance neobdrží signál pomocí parametru TimeSpan pro určení časového intervalu.

WaitOne(TimeSpan, Boolean)

Zablokuje aktuální vlákno, dokud aktuální instance neobdrží signál. Použije TimeSpan k určení časového intervalu a určí, jestli se má před čekáním ukončit synchronizační doména.

Explicitní implementace rozhraní

IDisposable.Dispose()

Toto rozhraní API podporuje produktovou infrastrukturu a není určené k použití přímo z uživatelského kódu.

Uvolní všechny prostředky používané nástrojem WaitHandle.

Metody rozšíření

GetSafeWaitHandle(WaitHandle)

Získá bezpečný popisovač pro nativní operační systém čekání popisovač.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

Nastaví bezpečný popisovač pro čekací úchyt nativního operačního systému.

Platí pro

Bezpečný přístup z více vláken

Tento typ je bezpečný pro přístup z více vláken.

Viz také