WaitHandle.WaitAny Metoda

Definice

Počká, až některý z prvků v zadaném poli přijme signál.

Přetížení

WaitAny(WaitHandle[])

Počká, až některý z prvků v zadaném poli přijme signál.

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 k určení časového intervalu.

WaitAny(WaitHandle[], TimeSpan)

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

WaitAny(WaitHandle[], Int32, Boolean)

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

WaitAny(WaitHandle[], TimeSpan, Boolean)

Čeká, až některý z prvků v zadaném poli obdrží signál, a to pomocí TimeSpan parametru k určení časového intervalu a určení, zda má být doména synchronizace ukončena před čekáním.

WaitAny(WaitHandle[])

Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs

Počká, až některý z prvků v zadaném poli přijme signál.

public:
 static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles);
public static int WaitAny (System.Threading.WaitHandle[] waitHandles);
static member WaitAny : System.Threading.WaitHandle[] -> int
Public Shared Function WaitAny (waitHandles As WaitHandle()) As Integer

Parametry

waitHandles
WaitHandle[]

Pole WaitHandle obsahující objekty, na které bude aktuální instance čekat.

Návraty

Index pole objektu, který splnil čekání.

Výjimky

Parametr waitHandles je null.

-nebo-

Jeden nebo více objektů v waitHandles poli je null.

Počet objektů v souboru waitHandles je větší, než systém povoluje.

waitHandles je pole bez prvků a verze rozhraní .NET Framework je 1.0 nebo 1.1.

Čekání bylo dokončeno, protože vlákno bylo ukončeno bez uvolnění mutex.

waitHandles je pole bez prvků a verze rozhraní .NET Framework je 2.0 nebo novější.

Pole waitHandles obsahuje transparentní proxy server pro WaitHandle objekt v jiné doméně aplikace.

Příklady

Následující příklad kódu ukazuje volání WaitAny metody .

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

AbandonedMutexException je novinka v rozhraní .NET Framework verze 2.0. V předchozích verzích metoda vracítrue, WaitAny pokud se čekání dokončí, protože je zrušena funkce mutex. Opuštěný mutex často značí závažnou chybu kódování. V případě systémového mutexu to může znamenat, že aplikace byla náhle ukončena (například pomocí Správce úloh systému Windows). Výjimka obsahuje informace užitečné pro ladění.

Metoda WaitAny vyvolá pouze AbandonedMutexException po dokončení čekání kvůli opuštěné mutex. Pokud waitHandles obsahuje uvolněný mutex s nižším číslem indexu než opuštěný mutex, WaitAny metoda se normálně dokončí a výjimka se nevyvolá.

Poznámka

Ve verzích rozhraní .NET Framework starších než verze 2.0, pokud vlákno ukončí nebo přeruší bez explicitního uvolnění Mutex, a který Mutex je na indexu 0 (nula) v poli v WaitAny jiném vlákně, index vrácený metodou WaitAny je 128 místo 0.

Tato metoda vrátí při signálu jakýkoli popisovač. Pokud se během volání signalizují více než jeden objekt, návratovou hodnotou je index pole signalovaného objektu s nejmenší hodnotou indexu ze všech signalovaných objektů.

Maximální počet obslužných rutin čekání je 64 a 63, pokud je aktuální vlákno ve STA stavu.

Volání přetížení této metody je ekvivalentní volání WaitAny(WaitHandle[], Int32, Boolean) přetížení metody a zadání -1 (nebo Timeout.Infinite) pro millisecondsTimeout a true pro exitContext.

Platí pro

WaitAny(WaitHandle[], Int32)

Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs

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

public:
 static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, int millisecondsTimeout);
public static int WaitAny (System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout);
static member WaitAny : System.Threading.WaitHandle[] * int -> int
Public Shared Function WaitAny (waitHandles As WaitHandle(), millisecondsTimeout As Integer) As Integer

Parametry

waitHandles
WaitHandle[]

Pole WaitHandle obsahující objekty, na které bude aktuální instance čekat.

millisecondsTimeout
Int32

Počet milisekund, které se mají čekat, nebo Infinite (-1) čekání na neomezenou dobu.

Návraty

Index pole objektu, který splnil čekání, nebo WaitTimeout pokud žádný objekt neuspokojil čekání a časový interval ekvivalentní.millisecondsTimeout

Výjimky

Parametr waitHandles je null.

-nebo-

Jeden nebo více objektů v waitHandles poli je null.

Počet objektů v souboru waitHandles je větší, než systém povoluje.

millisecondsTimeout je záporné číslo jiné než -1, které představuje nekonečný časový limit.

Čekání bylo dokončeno, protože vlákno bylo ukončeno bez uvolnění mutex.

waitHandles je pole bez prvků.

Pole waitHandles obsahuje transparentní proxy server pro WaitHandle objekt v jiné doméně aplikace.

Poznámky

Pokud millisecondsTimeout je nula, metoda neblokuje. Otestuje stav obslužných rutin čekání a okamžitě se vrátí.

Metoda WaitAny vyvolá pouze AbandonedMutexException po dokončení čekání kvůli opuštěné mutex. Pokud waitHandles obsahuje uvolněný mutex s nižším číslem indexu než opuštěný mutex, WaitAny metoda se normálně dokončí a výjimka se nevyvolá.

Tato metoda vrátí při ukončení čekání, a to buď při signálu některého z popisovačů, nebo když dojde k vypršení časového limitu. Pokud se během volání signalizují více než jeden objekt, návratovou hodnotou je index pole signalovaného objektu s nejmenší hodnotou indexu ze všech signalovaných objektů.

Maximální počet obslužných rutin čekání je 64 a 63, pokud je aktuální vlákno ve STA stavu.

Volání přetížení této metody je stejné jako volání WaitAny(WaitHandle[], Int32, Boolean) přetížení a zadání false pro exitContext.

Platí pro

WaitAny(WaitHandle[], TimeSpan)

Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs

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

public:
 static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, TimeSpan timeout);
public static int WaitAny (System.Threading.WaitHandle[] waitHandles, TimeSpan timeout);
static member WaitAny : System.Threading.WaitHandle[] * TimeSpan -> int
Public Shared Function WaitAny (waitHandles As WaitHandle(), timeout As TimeSpan) As Integer

Parametry

waitHandles
WaitHandle[]

Pole WaitHandle obsahující objekty, na které bude aktuální instance čekat.

timeout
TimeSpan

A TimeSpan , který představuje počet milisekund čekání, nebo , TimeSpan který představuje -1 milisekund čekání neomezeně.

Návraty

Index pole objektu, který splnil čekání, nebo WaitTimeout pokud žádný objekt neuspokojil čekání a časový interval ekvivalentní.timeout

Výjimky

Parametr waitHandles je null.

-nebo-

Jeden nebo více objektů v waitHandles poli je null.

Počet objektů v souboru waitHandles je větší, než systém povoluje.

timeout je záporné číslo jiné než -1 milisekund, které představuje nekonečný časový limit.

-nebo-

timeout je větší než Int32.MaxValue.

Čekání bylo dokončeno, protože vlákno bylo ukončeno bez uvolnění mutex.

waitHandles je pole bez prvků.

Pole waitHandles obsahuje transparentní proxy server pro WaitHandle objekt v jiné doméně aplikace.

Poznámky

Pokud timeout je nula, metoda neblokuje. Otestuje stav obslužných rutin čekání a okamžitě se vrátí.

Metoda WaitAny vyvolá pouze AbandonedMutexException po dokončení čekání kvůli opuštěné mutex. Pokud waitHandles obsahuje uvolněný mutex s nižším číslem indexu než opuštěný mutex, WaitAny metoda se normálně dokončí a výjimka se nevyvolá.

Tato metoda vrátí, když čekání skončí, buď při signálu některého z popisovačů, nebo když dojde k vypršení časového limitu. Pokud se během volání signalizují více než jeden objekt, návratovou hodnotou je index pole signalovaného objektu s nejmenší hodnotou indexu ze všech signalovaných objektů.

Maximální počet obslužných rutin čekání je 64 a 63, pokud je aktuální vlákno ve STA stavu.

Maximální hodnota pro timeout je Int32.MaxValue.

Volání přetížení této metody je stejné jako volání WaitAny(WaitHandle[], TimeSpan, Boolean) přetížení a zadání false pro exitContext.

Platí pro

WaitAny(WaitHandle[], Int32, Boolean)

Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs

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

public:
 static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, int millisecondsTimeout, bool exitContext);
public static int WaitAny (System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext);
static member WaitAny : System.Threading.WaitHandle[] * int * bool -> int
Public Shared Function WaitAny (waitHandles As WaitHandle(), millisecondsTimeout As Integer, exitContext As Boolean) As Integer

Parametry

waitHandles
WaitHandle[]

Pole WaitHandle obsahující objekty, na které bude aktuální instance čekat.

millisecondsTimeout
Int32

Počet milisekund, které se mají čekat, nebo Infinite (-1) čekání na neomezenou dobu.

exitContext
Boolean

trueopustit synchronizační doménu pro kontext před čekáním (pokud je v synchronizovaném kontextu) a následně ji znovu získat; v opačném případě . false

Návraty

Index pole objektu, který splnil čekání, nebo WaitTimeout pokud žádný objekt neuspokojil čekání a časový interval ekvivalentní.millisecondsTimeout

Výjimky

Parametr waitHandles je null.

-nebo-

Jeden nebo více objektů v waitHandles poli je null.

Počet objektů v souboru waitHandles je větší, než systém povoluje.

waitHandles je pole bez prvků a verze rozhraní .NET Framework je 1.0 nebo 1.1.

millisecondsTimeout je záporné číslo jiné než -1, které představuje nekonečný časový limit.

Čekání bylo dokončeno, protože vlákno bylo ukončeno bez uvolnění mutex.

waitHandles je pole bez prvků a verze rozhraní .NET Framework je 2.0 nebo novější.

Pole waitHandles obsahuje transparentní proxy server pro WaitHandle objekt v jiné doméně aplikace.

Příklady

Následující příklad kódu ukazuje, jak použít fond vláken k vyhledání souboru na více discích současně. V případě požadavků na místo se prohledá pouze kořenový adresář každého disku.

using namespace System;
using namespace System::IO;
using namespace System::Threading;
ref class Search
{
private:

   // Maintain state information to pass to FindCallback.
   ref class State
   {
   public:
      AutoResetEvent^ autoEvent;
      String^ fileName;
      State( AutoResetEvent^ autoEvent, String^ fileName )
         : autoEvent( autoEvent ), fileName( fileName )
      {}

   };


public:
   array<AutoResetEvent^>^autoEvents;
   array<String^>^diskLetters;

   // Search for stateInfo->fileName.
   void FindCallback( Object^ state )
   {
      State^ stateInfo = dynamic_cast<State^>(state);
      
      // Signal if the file is found.
      if ( File::Exists( stateInfo->fileName ) )
      {
         stateInfo->autoEvent->Set();
      }
   }

   Search()
   {
      
      // Retrieve an array of disk letters.
      diskLetters = Environment::GetLogicalDrives();
      autoEvents = gcnew array<AutoResetEvent^>(diskLetters->Length);
      for ( int i = 0; i < diskLetters->Length; i++ )
      {
         autoEvents[ i ] = gcnew AutoResetEvent( false );

      }
   }


   // Search for fileName in the root directory of all disks.
   void FindFile( String^ fileName )
   {
      for ( int i = 0; i < diskLetters->Length; i++ )
      {
         Console::WriteLine(  "Searching for {0} on {1}.", fileName, diskLetters[ i ] );
         ThreadPool::QueueUserWorkItem( gcnew WaitCallback( this, &Search::FindCallback ), gcnew State( autoEvents[ i ],String::Concat( diskLetters[ i ], fileName ) ) );

      }
      
      // Wait for the first instance of the file to be found.
      int index = WaitHandle::WaitAny( autoEvents, 3000, false );
      if ( index == WaitHandle::WaitTimeout )
      {
         Console::WriteLine( "\n{0} not found.", fileName );
      }
      else
      {
         Console::WriteLine( "\n{0} found on {1}.", fileName, diskLetters[ index ] );
      }
   }

};

int main()
{
   Search^ search = gcnew Search;
   search->FindFile( "SomeFile.dat" );
}
using System;
using System.IO;
using System.Threading;

class Test
{
    static void Main()
    {
        Search search = new Search();
        search.FindFile("SomeFile.dat");
    }
}

class Search
{
    // Maintain state information to pass to FindCallback.
    class State
    {
        public AutoResetEvent autoEvent;
        public string         fileName;

        public State(AutoResetEvent autoEvent, string fileName)
        {
            this.autoEvent    = autoEvent;
            this.fileName     = fileName;
        }
    }

    AutoResetEvent[] autoEvents;
    String[] diskLetters;

    public Search()
    {
        // Retrieve an array of disk letters.
        diskLetters = Environment.GetLogicalDrives();

        autoEvents = new AutoResetEvent[diskLetters.Length];
        for(int i = 0; i < diskLetters.Length; i++)
        {
            autoEvents[i] = new AutoResetEvent(false);
        }
    }

    // Search for fileName in the root directory of all disks.
    public void FindFile(string fileName)
    {
        for(int i = 0; i < diskLetters.Length; i++)
        {
            Console.WriteLine("Searching for {0} on {1}.",
                fileName, diskLetters[i]);
            ThreadPool.QueueUserWorkItem(
                new WaitCallback(FindCallback), 
                new State(autoEvents[i], diskLetters[i] + fileName));
        }

        // Wait for the first instance of the file to be found.
        int index = WaitHandle.WaitAny(autoEvents, 3000, false);
        if(index == WaitHandle.WaitTimeout)
        {
            Console.WriteLine("\n{0} not found.", fileName);
        }
        else
        {
            Console.WriteLine("\n{0} found on {1}.", fileName,
                diskLetters[index]);
        }
    }

    // Search for stateInfo.fileName.
    void FindCallback(object state)
    {
        State stateInfo = (State)state;

        // Signal if the file is found.
        if(File.Exists(stateInfo.fileName))
        {
            stateInfo.autoEvent.Set();
        }
    }
}
Imports System.IO
Imports System.Threading

Public Class Test

    <MTAThread> _
    Shared Sub Main()
        Dim search As New Search()
        search.FindFile("SomeFile.dat")
    End Sub    
End Class

Public Class Search

    ' Maintain state information to pass to FindCallback.
    Class State
        Public autoEvent As AutoResetEvent 
        Public fileName As String         

        Sub New(anEvent As AutoResetEvent, fName As String)
            autoEvent = anEvent
            fileName = fName
        End Sub
    End Class

    Dim autoEvents() As AutoResetEvent
    Dim diskLetters() As String

    Sub New()

        ' Retrieve an array of disk letters.
        diskLetters = Environment.GetLogicalDrives()

        autoEvents = New AutoResetEvent(diskLetters.Length - 1) {}
        For i As Integer = 0 To diskLetters.Length - 1
            autoEvents(i) = New AutoResetEvent(False)
        Next i
    End Sub    
    
    ' Search for fileName in the root directory of all disks.
    Sub FindFile(fileName As String)
        For i As Integer = 0 To diskLetters.Length - 1
            Console.WriteLine("Searching for {0} on {1}.", _
                fileName, diskLetters(i))
        
            ThreadPool.QueueUserWorkItem(AddressOf FindCallback, _ 
                New State(autoEvents(i), diskLetters(i) & fileName))
        Next i

        ' Wait for the first instance of the file to be found.
        Dim index As Integer = _
            WaitHandle.WaitAny(autoEvents, 3000, False)
        If index = WaitHandle.WaitTimeout
            Console.WriteLine(vbCrLf & "{0} not found.", fileName)
        Else
            Console.WriteLine(vbCrLf & "{0} found on {1}.", _
                fileName, diskLetters(index))
        End If
    End Sub

    ' Search for stateInfo.fileName.
    Sub FindCallback(state As Object)
        Dim stateInfo As State = DirectCast(state, State)

        ' Signal if the file is found.
        If File.Exists(stateInfo.fileName) Then
            stateInfo.autoEvent.Set()
        End If
    End Sub

End Class

Poznámky

Pokud millisecondsTimeout je nula, metoda neblokuje. Otestuje stav obslužných rutin čekání a okamžitě se vrátí.

Metoda WaitAny vyvolá pouze AbandonedMutexException po dokončení čekání kvůli opuštěné mutex. Pokud waitHandles obsahuje uvolněný mutex s nižším číslem indexu než opuštěný mutex, WaitAny metoda se normálně dokončí a výjimka se nevyvolá. Opuštěný mutex často značí závažnou chybu kódování. V případě systémového mutexu to může znamenat, že aplikace byla náhle ukončena (například pomocí Správce úloh systému Windows). Výjimka obsahuje informace užitečné pro ladění.

Tato metoda vrátí při ukončení čekání, a to buď při signálu některého z popisovačů, nebo když dojde k vypršení časového limitu. Pokud se během volání signalizují více než jeden objekt, návratovou hodnotou je index pole signalovaného objektu s nejmenší hodnotou indexu ze všech signalovaných objektů.

Maximální počet obslužných rutin čekání je 64 a 63, pokud je aktuální vlákno ve STA stavu.

Ukončení kontextu

Parametr exitContext nemá žádný vliv, pokud tato metoda není volána z nevýkonných spravovaných kontextů. Spravovaný kontext může být nevýchozí, pokud se vlákno nachází uvnitř volání instance třídy odvozené z ContextBoundObject. I když aktuálně spouštíte metodu pro třídu, která není odvozená z ContextBoundObject, jako Stringje , můžete být v nevýchozím kontextu, pokud je ve vašem zásobníku ContextBoundObject v aktuální doméně aplikace.

Když se váš kód spouští v nevýchozím kontextu, určení true for exitContext způsobí, že vlákno ukončí nevýchozí spravovaný kontext (tj. pro přechod do výchozího kontextu) před spuštěním této metody. Vlákno se po dokončení volání této metody vrátí k původnímu nevýchozí kontext.

Ukončení kontextu může být užitečné, pokud kontextová třída má SynchronizationAttribute atribut . V takovém případě jsou všechna volání členů třídy automaticky synchronizována a doména synchronizace je celé tělo kódu pro třídu. Pokud kód v zásobníku volání člena volá tuto metodu a určuje true pro exitContext, vlákno opustí synchronizační doménu, což umožňuje vlákno blokované při volání libovolného člena objektu pokračovat. Když tato metoda vrátí, vlákno, které provedlo volání, musí počkat na opětovné zadání synchronizační domény.

Platí pro

WaitAny(WaitHandle[], TimeSpan, Boolean)

Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs

Čeká, až některý z prvků v zadaném poli obdrží signál, a to pomocí TimeSpan parametru k určení časového intervalu a určení, zda má být doména synchronizace ukončena před čekáním.

public:
 static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, TimeSpan timeout, bool exitContext);
public static int WaitAny (System.Threading.WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext);
static member WaitAny : System.Threading.WaitHandle[] * TimeSpan * bool -> int
Public Shared Function WaitAny (waitHandles As WaitHandle(), timeout As TimeSpan, exitContext As Boolean) As Integer

Parametry

waitHandles
WaitHandle[]

Pole WaitHandle obsahující objekty, na které bude aktuální instance čekat.

timeout
TimeSpan

A TimeSpan , který představuje počet milisekund čekání, nebo , TimeSpan který představuje -1 milisekund čekání neomezeně.

exitContext
Boolean

trueopustit synchronizační doménu pro kontext před čekáním (pokud je v synchronizovaném kontextu) a následně ji znovu získat; v opačném případě . false

Návraty

Index pole objektu, který splnil čekání, nebo WaitTimeout pokud žádný objekt neuspokojil čekání a časový interval ekvivalentní.timeout

Výjimky

Parametr waitHandles je null.

-nebo-

Jeden nebo více objektů v waitHandles poli je null.

Počet objektů v souboru waitHandles je větší, než systém povoluje.

waitHandles je pole bez prvků a verze rozhraní .NET Framework je 1.0 nebo 1.1.

timeout je záporné číslo jiné než -1 milisekund, které představuje nekonečný časový limit.

-nebo-

timeout je větší než Int32.MaxValue.

Čekání bylo dokončeno, protože vlákno bylo ukončeno bez uvolnění mutex.

waitHandles je pole bez prvků a verze rozhraní .NET Framework je 2.0 nebo novější.

Pole waitHandles obsahuje transparentní proxy server pro WaitHandle objekt v jiné doméně aplikace.

Příklady

Následující příklad kódu ukazuje, jak použít fond vláken k vyhledání souboru na více discích současně. V případě požadavků na místo se prohledá pouze kořenový adresář každého disku.

using namespace System;
using namespace System::IO;
using namespace System::Threading;
ref class Search
{
private:

   // Maintain state information to pass to FindCallback.
   ref class State
   {
   public:
      AutoResetEvent^ autoEvent;
      String^ fileName;
      State( AutoResetEvent^ autoEvent, String^ fileName )
         : autoEvent( autoEvent ), fileName( fileName )
      {}

   };


public:
   array<AutoResetEvent^>^autoEvents;
   array<String^>^diskLetters;

   // Search for stateInfo->fileName.
   void FindCallback( Object^ state )
   {
      State^ stateInfo = dynamic_cast<State^>(state);
      
      // Signal if the file is found.
      if ( File::Exists( stateInfo->fileName ) )
      {
         stateInfo->autoEvent->Set();
      }
   }

   Search()
   {
      
      // Retrieve an array of disk letters.
      diskLetters = Environment::GetLogicalDrives();
      autoEvents = gcnew array<AutoResetEvent^>(diskLetters->Length);
      for ( int i = 0; i < diskLetters->Length; i++ )
      {
         autoEvents[ i ] = gcnew AutoResetEvent( false );

      }
   }


   // Search for fileName in the root directory of all disks.
   void FindFile( String^ fileName )
   {
      for ( int i = 0; i < diskLetters->Length; i++ )
      {
         Console::WriteLine(  "Searching for {0} on {1}.", fileName, diskLetters[ i ] );
         ThreadPool::QueueUserWorkItem( gcnew WaitCallback( this, &Search::FindCallback ), gcnew State( autoEvents[ i ],String::Concat( diskLetters[ i ], fileName ) ) );

      }
      
      // Wait for the first instance of the file to be found.
      int index = WaitHandle::WaitAny( autoEvents, TimeSpan(0,0,3), false );
      if ( index == WaitHandle::WaitTimeout )
      {
         Console::WriteLine( "\n{0} not found.", fileName );
      }
      else
      {
         Console::WriteLine( "\n{0} found on {1}.", fileName, diskLetters[ index ] );
      }
   }

};

int main()
{
   Search^ search = gcnew Search;
   search->FindFile( "SomeFile.dat" );
}
using System;
using System.IO;
using System.Threading;

class Test
{
    static void Main()
    {
        Search search = new Search();
        search.FindFile("SomeFile.dat");
    }
}

class Search
{
    // Maintain state information to pass to FindCallback.
    class State
    {
        public AutoResetEvent autoEvent;
        public string         fileName;

        public State(AutoResetEvent autoEvent, string fileName)
        {
            this.autoEvent    = autoEvent;
            this.fileName     = fileName;
        }
    }

    AutoResetEvent[] autoEvents;
    String[] diskLetters;

    public Search()
    {
        // Retrieve an array of disk letters.
        diskLetters = Environment.GetLogicalDrives();

        autoEvents = new AutoResetEvent[diskLetters.Length];
        for(int i = 0; i < diskLetters.Length; i++)
        {
            autoEvents[i] = new AutoResetEvent(false);
        }
    }

    // Search for fileName in the root directory of all disks.
    public void FindFile(string fileName)
    {
        for(int i = 0; i < diskLetters.Length; i++)
        {
            Console.WriteLine("Searching for {0} on {1}.",
                fileName, diskLetters[i]);
            ThreadPool.QueueUserWorkItem(
                new WaitCallback(FindCallback), 
                new State(autoEvents[i], diskLetters[i] + fileName));
        }

        // Wait for the first instance of the file to be found.
        int index = WaitHandle.WaitAny(
            autoEvents, new TimeSpan(0, 0, 3), false);
        if(index == WaitHandle.WaitTimeout)
        {
            Console.WriteLine("\n{0} not found.", fileName);
        }
        else
        {
            Console.WriteLine("\n{0} found on {1}.", fileName,
                diskLetters[index]);
        }
    }

    // Search for stateInfo.fileName.
    void FindCallback(object state)
    {
        State stateInfo = (State)state;

        // Signal if the file is found.
        if(File.Exists(stateInfo.fileName))
        {
            stateInfo.autoEvent.Set();
        }
    }
}
Imports System.IO
Imports System.Threading

Public Class Test

    <MTAThread> _
    Shared Sub Main()
        Dim search As New Search()
        search.FindFile("SomeFile.dat")
    End Sub    
End Class

Public Class Search

    ' Maintain state information to pass to FindCallback.
    Class State
        Public autoEvent As AutoResetEvent 
        Public fileName As String         

        Sub New(anEvent As AutoResetEvent, fName As String)
            autoEvent = anEvent
            fileName = fName
        End Sub
    End Class

    Dim autoEvents() As AutoResetEvent
    Dim diskLetters() As String

    Sub New()

        ' Retrieve an array of disk letters.
        diskLetters = Environment.GetLogicalDrives()

        autoEvents = New AutoResetEvent(diskLetters.Length - 1) {}
        For i As Integer = 0 To diskLetters.Length - 1
            autoEvents(i) = New AutoResetEvent(False)
        Next i
    End Sub    
    
    ' Search for fileName in the root directory of all disks.
    Sub FindFile(fileName As String)
        For i As Integer = 0 To diskLetters.Length - 1
            Console.WriteLine("Searching for {0} on {1}.", _
                fileName, diskLetters(i))
        
            ThreadPool.QueueUserWorkItem(AddressOf FindCallback, _ 
                New State(autoEvents(i), diskLetters(i) & fileName))
        Next i

        ' Wait for the first instance of the file to be found.
        Dim index As Integer = WaitHandle.WaitAny( _
            autoEvents, New TimeSpan(0, 0, 3), False)
        If index = WaitHandle.WaitTimeout
            Console.WriteLine(vbCrLf & "{0} not found.", fileName)
        Else
            Console.WriteLine(vbCrLf & "{0} found on {1}.", _
                fileName, diskLetters(index))
        End If
    End Sub

    ' Search for stateInfo.fileName.
    Sub FindCallback(state As Object)
        Dim stateInfo As State = DirectCast(state, State)

        ' Signal if the file is found.
        If File.Exists(stateInfo.fileName) Then
            stateInfo.autoEvent.Set()
        End If
    End Sub

End Class

Poznámky

Pokud timeout je nula, metoda neblokuje. Otestuje stav obslužných rutin čekání a okamžitě se vrátí.

Metoda WaitAny vyvolá pouze AbandonedMutexException po dokončení čekání kvůli opuštěné mutex. Pokud waitHandles obsahuje uvolněný mutex s nižším číslem indexu než opuštěný mutex, WaitAny metoda se normálně dokončí a výjimka se nevyvolá. Opuštěný mutex často značí závažnou chybu kódování. V případě systémového mutexu to může znamenat, že aplikace byla náhle ukončena (například pomocí Správce úloh systému Windows). Výjimka obsahuje informace užitečné pro ladění.

Tato metoda vrátí, když čekání skončí, buď při signálu některého z popisovačů, nebo když dojde k vypršení časového limitu. Pokud se během volání signalizují více než jeden objekt, návratovou hodnotou je index pole signalovaného objektu s nejmenší hodnotou indexu ze všech signalovaných objektů.

Maximální počet obslužných rutin čekání je 64 a 63, pokud je aktuální vlákno ve STA stavu.

Maximální hodnota pro timeout je Int32.MaxValue.

Ukončení kontextu

Parametr exitContext nemá žádný vliv, pokud tato metoda není volána z nevýkonných spravovaných kontextů. Spravovaný kontext může být nevýchozí, pokud se vlákno nachází uvnitř volání instance třídy odvozené z ContextBoundObject. I když aktuálně spouštíte metodu pro třídu, která není odvozená z ContextBoundObject, jako Stringje , můžete být v nevýchozím kontextu, pokud je ve vašem zásobníku ContextBoundObject v aktuální doméně aplikace.

Když se váš kód spouští v nevýchozím kontextu, určení true for exitContext způsobí, že vlákno ukončí nevýchozí spravovaný kontext (tj. pro přechod do výchozího kontextu) před spuštěním této metody. Vlákno se po dokončení volání této metody vrátí k původnímu nevýchozí kontext.

Ukončení kontextu může být užitečné, pokud kontextová třída má SynchronizationAttribute atribut . V takovém případě jsou všechna volání členů třídy automaticky synchronizována a doména synchronizace je celé tělo kódu pro třídu. Pokud kód v zásobníku volání člena volá tuto metodu a určuje true pro exitContext, vlákno opustí synchronizační doménu, což umožňuje vlákno blokované při volání libovolného člena objektu pokračovat. Když tato metoda vrátí, vlákno, které provedlo volání, musí počkat na opětovné zadání synchronizační domény.

Platí pro