WaitHandle.WaitAny Metodo

Definizione

Attende che uno degli elementi nella matrice specificata riceva un segnale.

Overload

WaitAny(WaitHandle[])

Attende che uno degli elementi nella matrice specificata riceva un segnale.

WaitAny(WaitHandle[], Int32)

Attende che uno degli elementi nella matrice specificata riceva un segnale, usando un intero con segno a 32 bit per specificare l'intervallo di tempo.

WaitAny(WaitHandle[], TimeSpan)

Attende che uno degli elementi nella matrice specificata riceva un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo.

WaitAny(WaitHandle[], Int32, Boolean)

Attende che uno degli elementi nella matrice specificata riceva 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.

WaitAny(WaitHandle[], TimeSpan, Boolean)

Attende che uno degli elementi nella matrice specificata riceva un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.

WaitAny(WaitHandle[])

Origine:
WaitHandle.cs
Origine:
WaitHandle.cs
Origine:
WaitHandle.cs

Attende che uno degli elementi nella matrice specificata riceva un segnale.

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

Parametri

waitHandles
WaitHandle[]

Matrice WaitHandle contenente gli oggetti per i quali l'istanza corrente attenderà.

Restituisce

Indice della matrice dell'oggetto che ha soddisfatto l'attesa.

Eccezioni

Il valore del parametro waitHandles è null.

-oppure-

Uno o più oggetti nella matrice waitHandles sono null.

Il numero di oggetti in waitHandles è maggiore di quello consentito dal sistema.

waitHandles è una matrice senza elementi e la versione di .NET Framework è 1.0 o 1.1.

L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.

waitHandles è una matrice senza elementi e la versione di .NET Framework è la 2.0 o successiva.

La matrice waitHandles contiene un proxy trasparente per un oggetto WaitHandle in un altro dominio di applicazione.

Esempio

Nell'esempio di codice seguente viene illustrata la chiamata al WaitAny metodo .

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

Commenti

AbandonedMutexException è una novità di .NET Framework versione 2.0. Nelle versioni precedenti, il WaitAny metodo restituisce true se l'attesa viene completata perché un mutex viene abbandonato. 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 WaitAny metodo genera un'eccezione AbandonedMutexException solo quando l'attesa viene completata a causa di un mutex abbandonato. Se waitHandles contiene un mutex rilasciato con un numero di indice inferiore rispetto al mutex abbandonato, il WaitAny metodo viene completato normalmente e l'eccezione non viene generata.

Nota

Nelle versioni di .NET Framework precedenti alla versione 2.0, se un thread viene chiuso o interrotto senza rilasciare in modo esplicito un Mutexoggetto e che Mutex si trova in corrispondenza dell'indice 0 (zero) in una matrice in un WaitAny altro thread, l'indice restituito da WaitAny è 128 anziché 0.

Questo metodo restituisce quando viene segnalato un handle. Se più di un oggetto viene segnalato durante la chiamata, il valore restituito è l'indice di matrice dell'oggetto segnalato con il valore di indice più piccolo di tutti gli oggetti segnalato.

Il numero massimo di handle di attesa è 64 e 63 se il thread corrente è in STA stato.

La chiamata a questo overload del metodo equivale a chiamare l'overload del WaitAny(WaitHandle[], Int32, Boolean) metodo e specificare -1 (o Timeout.Infinite) per millisecondsTimeout e true per exitContext.

Si applica a

WaitAny(WaitHandle[], Int32)

Origine:
WaitHandle.cs
Origine:
WaitHandle.cs
Origine:
WaitHandle.cs

Attende che uno degli elementi nella matrice specificata riceva un segnale, usando un intero con segno a 32 bit per specificare l'intervallo di tempo.

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

Parametri

waitHandles
WaitHandle[]

Matrice WaitHandle contenente gli oggetti per i quali l'istanza corrente attenderà.

millisecondsTimeout
Int32

Numero di millisecondi di attesa oppure Infinite (-1) per un'attesa indefinita.

Restituisce

Indice della matrice dell'oggetto che ha soddisfatto l'attesa oppure WaitTimeout se nessun oggetto ha soddisfatto l'attesa ed è trascorso un intervallo di tempo equivalente a millisecondsTimeout.

Eccezioni

Il valore del parametro waitHandles è null.

-oppure-

Uno o più oggetti nella matrice waitHandles sono null.

Il numero di oggetti in waitHandles è maggiore di quello consentito dal sistema.

millisecondsTimeout è un numero negativo diverso da -1, che rappresenta un timeout infinito.

L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.

waitHandles è una matrice senza elementi.

La matrice waitHandles contiene un proxy trasparente per un oggetto WaitHandle in un altro dominio di applicazione.

Commenti

Se millisecondsTimeout è zero, il metodo non viene bloccato. Verifica lo stato degli handle di attesa e restituisce immediatamente.

Il WaitAny metodo genera un'eccezione AbandonedMutexException solo quando l'attesa viene completata a causa di un mutex abbandonato. Se waitHandles contiene un mutex rilasciato con un numero di indice inferiore rispetto al mutex abbandonato, il WaitAny metodo viene completato normalmente e l'eccezione non viene generata.

Questo metodo restituisce quando termina l'attesa, quando uno degli handle viene segnalato o quando si verifica un timeout. Se più di un oggetto viene segnalato durante la chiamata, il valore restituito è l'indice di matrice dell'oggetto segnalato con il valore di indice più piccolo di tutti gli oggetti segnalato.

Il numero massimo di handle di attesa è 64 e 63 se il thread corrente è in STA stato.

La chiamata a questo overload del metodo equivale a chiamare l'overload WaitAny(WaitHandle[], Int32, Boolean) e specificare false per exitContext.

Si applica a

WaitAny(WaitHandle[], TimeSpan)

Origine:
WaitHandle.cs
Origine:
WaitHandle.cs
Origine:
WaitHandle.cs

Attende che uno degli elementi nella matrice specificata riceva un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo.

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

Parametri

waitHandles
WaitHandle[]

Matrice WaitHandle contenente gli oggetti per i quali l'istanza corrente attenderà.

timeout
TimeSpan

Oggetto TimeSpan che rappresenta il numero di millisecondi di attesa oppure TimeSpan che rappresenta -1 millisecondi per un'attesa indefinita.

Restituisce

Indice della matrice dell'oggetto che ha soddisfatto l'attesa oppure WaitTimeout se nessun oggetto ha soddisfatto l'attesa ed è trascorso un intervallo di tempo equivalente a timeout.

Eccezioni

Il valore del parametro waitHandles è null.

-oppure-

Uno o più oggetti nella matrice waitHandles sono null.

Il numero di oggetti in waitHandles è maggiore di quello consentito dal sistema.

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.

waitHandles è una matrice senza elementi.

La matrice waitHandles contiene un proxy trasparente per un oggetto WaitHandle in un altro dominio di applicazione.

Commenti

Se timeout è zero, il metodo non viene bloccato. Verifica lo stato degli handle di attesa e restituisce immediatamente.

Il WaitAny metodo genera un'eccezione AbandonedMutexException solo quando l'attesa viene completata a causa di un mutex abbandonato. Se waitHandles contiene un mutex rilasciato con un numero di indice inferiore rispetto al mutex abbandonato, il WaitAny metodo viene completato normalmente e l'eccezione non viene generata.

Questo metodo restituisce quando termina l'attesa, quando uno degli handle viene segnalato o quando si verifica un timeout. Se più di un oggetto viene segnalato durante la chiamata, il valore restituito è l'indice di matrice dell'oggetto segnalato con il valore di indice più piccolo di tutti gli oggetti segnalato.

Il numero massimo di handle di attesa è 64 e 63 se il thread corrente è in STA stato.

Il valore massimo per timeout è Int32.MaxValue.

La chiamata a questo overload del metodo equivale a chiamare l'overload WaitAny(WaitHandle[], TimeSpan, Boolean) e specificare false per exitContext.

Si applica a

WaitAny(WaitHandle[], Int32, Boolean)

Origine:
WaitHandle.cs
Origine:
WaitHandle.cs
Origine:
WaitHandle.cs

Attende che uno degli elementi nella matrice specificata riceva 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:
 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

Parametri

waitHandles
WaitHandle[]

Matrice WaitHandle contenente gli oggetti per i quali l'istanza corrente attenderà.

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

Indice della matrice dell'oggetto che ha soddisfatto l'attesa oppure WaitTimeout se nessun oggetto ha soddisfatto l'attesa ed è trascorso un intervallo di tempo equivalente a millisecondsTimeout.

Eccezioni

Il valore del parametro waitHandles è null.

-oppure-

Uno o più oggetti nella matrice waitHandles sono null.

Il numero di oggetti in waitHandles è maggiore di quello consentito dal sistema.

waitHandles è una matrice senza elementi e la versione di .NET Framework è 1.0 o 1.1.

millisecondsTimeout è un numero negativo diverso da -1, che rappresenta un timeout infinito.

L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.

waitHandles è una matrice senza elementi e la versione di .NET Framework è la 2.0 o successiva.

La matrice waitHandles contiene un proxy trasparente per un oggetto WaitHandle in un altro dominio di applicazione.

Esempio

Nell'esempio di codice seguente viene illustrato come usare il pool di thread per cercare contemporaneamente un file in più dischi. Per considerazioni sullo spazio, viene eseguita la ricerca solo nella directory radice di ogni disco.

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

Commenti

Se millisecondsTimeout è zero, il metodo non viene bloccato. Verifica lo stato degli handle di attesa e restituisce immediatamente.

Il WaitAny metodo genera un'eccezione AbandonedMutexException solo quando l'attesa viene completata a causa di un mutex abbandonato. Se waitHandles contiene un mutex rilasciato con un numero di indice inferiore rispetto al mutex abbandonato, il WaitAny metodo viene completato normalmente e l'eccezione non viene generata. 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.

Questo metodo restituisce quando termina l'attesa, quando uno degli handle viene segnalato o quando si verifica un timeout. Se più di un oggetto viene segnalato durante la chiamata, il valore restituito è l'indice di matrice dell'oggetto segnalato con il valore di indice più piccolo di tutti gli oggetti segnalato.

Il numero massimo di handle di attesa è 64 e 63 se il thread corrente è in STA stato.

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.

Si applica a

WaitAny(WaitHandle[], TimeSpan, Boolean)

Origine:
WaitHandle.cs
Origine:
WaitHandle.cs
Origine:
WaitHandle.cs

Attende che uno degli elementi nella matrice specificata riceva un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.

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

Parametri

waitHandles
WaitHandle[]

Matrice WaitHandle contenente gli oggetti per i quali l'istanza corrente attenderà.

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

Indice della matrice dell'oggetto che ha soddisfatto l'attesa oppure WaitTimeout se nessun oggetto ha soddisfatto l'attesa ed è trascorso un intervallo di tempo equivalente a timeout.

Eccezioni

Il valore del parametro waitHandles è null.

-oppure-

Uno o più oggetti nella matrice waitHandles sono null.

Il numero di oggetti in waitHandles è maggiore di quello consentito dal sistema.

waitHandles è una matrice senza elementi e la versione di .NET Framework è 1.0 o 1.1.

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.

waitHandles è una matrice senza elementi e la versione di .NET Framework è la 2.0 o successiva.

La matrice waitHandles contiene un proxy trasparente per un oggetto WaitHandle in un altro dominio di applicazione.

Esempio

Nell'esempio di codice seguente viene illustrato come usare il pool di thread per cercare contemporaneamente un file in più dischi. Per considerazioni sullo spazio, viene eseguita la ricerca solo nella directory radice di ogni disco.

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

Commenti

Se timeout è zero, il metodo non viene bloccato. Verifica lo stato degli handle di attesa e restituisce immediatamente.

Il WaitAny metodo genera un'eccezione AbandonedMutexException solo quando l'attesa viene completata a causa di un mutex abbandonato. Se waitHandles contiene un mutex rilasciato con un numero di indice inferiore rispetto al mutex abbandonato, il WaitAny metodo viene completato normalmente e l'eccezione non viene generata. 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.

Questo metodo restituisce quando termina l'attesa, quando uno degli handle viene segnalato o quando si verifica un timeout. Se più di un oggetto viene segnalato durante la chiamata, il valore restituito è l'indice di matrice dell'oggetto segnalato con il valore di indice più piccolo di tutti gli oggetti segnalato.

Il numero massimo di handle di attesa è 64 e 63 se il thread corrente è in STA stato.

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.

Si applica a