WaitHandle.WaitAny Methode
Wichtig
Einige Informationen beziehen sich auf Vorabversionen, die vor dem Release ggf. grundlegend überarbeitet werden. Microsoft übernimmt hinsichtlich der hier bereitgestellten Informationen keine Gewährleistungen, seien sie ausdrücklich oder konkludent.
Wartet, bis Elemente im angegebenen Array ein Signal empfangen.
WaitAny(WaitHandle[]) |
Wartet, bis Elemente im angegebenen Array ein Signal empfangen. |
WaitAny(WaitHandle[], Int32) |
Wartet auf den Empfang eines Signals für alle Elemente im angegebenen Array und gibt das Zeitintervall mit einer 32-Bit-Ganzzahl mit Vorzeichen an. |
WaitAny(WaitHandle[], TimeSpan) |
Wartet auf den Empfang eines Signals für alle Elemente im angegebenen Array und gibt das Zeitintervall mit einem TimeSpan-Wert an. |
WaitAny(WaitHandle[], Int32, Boolean) |
Wartet, bis Elemente im angegebenen Array ein Signal empfangen, wobei eine 32-Bit-Ganzzahl mit Vorzeichen zum Angeben des Zeitintervalls verwendet wird, und gibt an, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll. |
WaitAny(WaitHandle[], TimeSpan, Boolean) |
Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen, wobei ein TimeSpan zum Angeben des Zeitintervalls verwendet wird, und gibt an, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll. |
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
Wartet, bis Elemente im angegebenen Array ein Signal empfangen.
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
Parameter
- waitHandles
- WaitHandle[]
Ein WaitHandle
-Array mit den Objekten, auf die die aktuelle Instanz wartet.
Gibt zurück
Der Arrayindex des Objekts, das den Wartevorgang erfüllt hat.
Ausnahmen
Der waitHandles
-Parameter ist null
.
- oder -
Mindestens ein Objekt im waitHandles
-Array ist null
.
Die Anzahl von Objekten in waitHandles
ist größer, als das System erlaubt.
waitHandles
ist ein Array ohne Elemente, und die .NET Framework-Version ist 1.0 oder 1.1.
Der Wartevorgang wird abgeschlossen, weil ein Thread beendet wurde, ohne ein Mutex freizugeben.
waitHandles
ist ein Array ohne Elemente, und die .NET Framework-Version ist 2.0 oder höher.
Das waitHandles
-Array enthält einen transparenten Proxy für ein WaitHandle in einer anderen Anwendungsdomäne.
Beispiele
Im folgenden Beispiel wird das Aufrufen der WaitAny-Methode veranschaulicht.
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).
Hinweise
AbandonedMutexExceptionist neu in der .NET Framework Version 2.0. In früheren Versionen gibt die WaitAny -Methode zurück true
, wenn die Wartezeit abgeschlossen ist, weil ein Mutex abgebrochen wird. Ein verlassener Mutex weist häufig auf einen schwerwiegenden Codierungsfehler hin. Im Fall eines systemweiten Mutex kann dies darauf hindeuten, dass eine Anwendung abrupt beendet wurde (z. B. mithilfe des Windows Task-Managers). Die Ausnahme enthält Informationen, die für das Debuggen nützlich sind.
Die WaitAny -Methode löst nur aus AbandonedMutexException , wenn die Wartezeit aufgrund eines abgebrochenen Mutex abgeschlossen ist. Wenn waitHandles
ein freigegebener Mutex mit einer niedrigeren Indexnummer als der verlassene Mutex enthält, wird die WaitAny Methode normal abgeschlossen, und die Ausnahme wird nicht ausgelöst.
Hinweis
Wenn ein Thread in Versionen der .NET Framework vor Version 2.0 beendet oder abgebrochen wird, ohne explizit einen Mutexfreizugeben, und das Mutex
sich bei Index 0 (Null) in einem Array in einem WaitAny
anderen Thread befindet, ist der von WaitAny
zurückgegebene Index 128 statt 0.
Diese Methode gibt zurück, wenn ein Handle signalisiert wird. Wenn während des Aufrufs mehr als ein Objekt signalisiert wird, ist der Rückgabewert der Arrayindex des signalierten Objekts mit dem kleinsten Indexwert aller signalierten Objekte.
Die maximale Anzahl der Wartehandles beträgt 64 und 63, wenn sich der aktuelle Thread im STA Zustand befindet.
Das Aufrufen dieser Methodenüberladung entspricht dem Aufrufen der Methodenüberladung und dem Angeben von WaitAny(WaitHandle[], Int32, Boolean) -1 (oder Timeout.Infinite) für millisecondsTimeout
und true
exitContext
für .
Gilt für:
.NET 9 und andere Versionen
Produkt | Versionen |
---|---|
.NET | Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9 |
.NET Framework | 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1 |
.NET Standard | 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1 |
UWP | 10.0 |
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
Wartet auf den Empfang eines Signals für alle Elemente im angegebenen Array und gibt das Zeitintervall mit einer 32-Bit-Ganzzahl mit Vorzeichen an.
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
Parameter
- waitHandles
- WaitHandle[]
Ein WaitHandle
-Array mit den Objekten, auf die die aktuelle Instanz wartet.
- millisecondsTimeout
- Int32
Die Anzahl von Millisekunden, die gewartet wird, oder Infinite (-1) für Warten ohne Timeout.
Gibt zurück
Der Arrayindex des Objekts, das den Wartevorgang erfüllt hat, oder WaitTimeout, wenn keines der Objekte den Wartevorgang erfüllt hat und ein Zeitintervall äquivalent zu millisecondsTimeout
vergangen ist.
Ausnahmen
Der waitHandles
-Parameter ist null
.
- oder -
Mindestens ein Objekt im waitHandles
-Array ist null
.
Die Anzahl von Objekten in waitHandles
ist größer, als das System erlaubt.
millisecondsTimeout
ist eine negative Zahl, jedoch nicht -1, was einen unbeschränkten Timeout darstellt.
Der Wartevorgang wird abgeschlossen, weil ein Thread beendet wurde, ohne ein Mutex freizugeben.
waitHandles
ist ein Array ohne Elemente.
Das waitHandles
-Array enthält einen transparenten Proxy für ein WaitHandle in einer anderen Anwendungsdomäne.
Hinweise
Wenn millisecondsTimeout
null ist, wird die -Methode nicht blockiert. Er testet den Status der Wartevorgänge und gibt sofort zurück.
Die WaitAny -Methode löst nur aus AbandonedMutexException , wenn die Wartezeit aufgrund eines abgebrochenen Mutex abgeschlossen ist. Wenn waitHandles
ein freigegebener Mutex mit einer niedrigeren Indexnummer als der verlassene Mutex enthält, wird die WaitAny Methode normal abgeschlossen, und die Ausnahme wird nicht ausgelöst.
Diese Methode gibt zurück, wenn die Wartezeit beendet wird, entweder wenn eines der Handles signalisiert wird oder wenn ein Timeout auftritt. Wenn während des Aufrufs mehr als ein Objekt signalisiert wird, ist der Rückgabewert der Arrayindex des signalierten Objekts mit dem kleinsten Indexwert aller signalierten Objekte.
Die maximale Anzahl der Wartehandles beträgt 64 und 63, wenn sich der aktuelle Thread im STA Zustand befindet.
Das Aufrufen dieser Methodenüberladung entspricht dem Aufrufen der WaitAny(WaitHandle[], Int32, Boolean) Überladung und dem Angeben false
für exitContext
.
Gilt für:
.NET 9 und andere Versionen
Produkt | Versionen |
---|---|
.NET | Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9 |
.NET Framework | 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1 |
.NET Standard | 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1 |
UWP | 10.0 |
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
Wartet auf den Empfang eines Signals für alle Elemente im angegebenen Array und gibt das Zeitintervall mit einem TimeSpan-Wert an.
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
Parameter
- waitHandles
- WaitHandle[]
Ein WaitHandle
-Array mit den Objekten, auf die die aktuelle Instanz wartet.
- timeout
- TimeSpan
Eine TimeSpan-Struktur, die die Anzahl der zu wartenden Millisekunden angibt, oder eine TimeSpan-Struktur, die -1 Millisekunden zum unendlichen Warten angibt.
Gibt zurück
Der Arrayindex des Objekts, das den Wartevorgang erfüllt hat, oder WaitTimeout, wenn keines der Objekte den Wartevorgang erfüllt hat und ein Zeitintervall äquivalent zu timeout
vergangen ist.
Ausnahmen
Der waitHandles
-Parameter ist null
.
- oder -
Mindestens ein Objekt im waitHandles
-Array ist null
.
Die Anzahl von Objekten in waitHandles
ist größer, als das System erlaubt.
timeout
ist eine negative Zahl ungleich -1 Millisekunden, die ein unendliches Timeout darstellt.
- oder -
timeout
ist größer als Int32.MaxValue.
Der Wartevorgang wird abgeschlossen, weil ein Thread beendet wurde, ohne ein Mutex freizugeben.
waitHandles
ist ein Array ohne Elemente.
Das waitHandles
-Array enthält einen transparenten Proxy für ein WaitHandle in einer anderen Anwendungsdomäne.
Hinweise
Wenn timeout
null ist, wird die -Methode nicht blockiert. Er testet den Status der Wartevorgänge und gibt sofort zurück.
Die WaitAny -Methode löst nur aus AbandonedMutexException , wenn die Wartezeit aufgrund eines abgebrochenen Mutex abgeschlossen ist. Wenn waitHandles
ein freigegebener Mutex mit einer niedrigeren Indexnummer als der verlassene Mutex enthält, wird die WaitAny Methode normal abgeschlossen, und die Ausnahme wird nicht ausgelöst.
Diese Methode gibt zurück, wenn die Wartezeit beendet wird, entweder wenn eines der Handles signalisiert wird oder wenn ein Timeout auftritt. Wenn während des Aufrufs mehr als ein Objekt signalisiert wird, ist der Rückgabewert der Arrayindex des signalierten Objekts mit dem kleinsten Indexwert aller signalierten Objekte.
Die maximale Anzahl der Wartehandles beträgt 64 und 63, wenn sich der aktuelle Thread im STA Zustand befindet.
Der Maximalwert für timeout
ist Int32.MaxValue.
Das Aufrufen dieser Methodenüberladung entspricht dem Aufrufen der WaitAny(WaitHandle[], TimeSpan, Boolean) Überladung und dem Angeben false
für exitContext
.
Gilt für:
.NET 9 und andere Versionen
Produkt | Versionen |
---|---|
.NET | Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9 |
.NET Framework | 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1 |
.NET Standard | 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1 |
UWP | 10.0 |
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
Wartet, bis Elemente im angegebenen Array ein Signal empfangen, wobei eine 32-Bit-Ganzzahl mit Vorzeichen zum Angeben des Zeitintervalls verwendet wird, und gibt an, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll.
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
Parameter
- waitHandles
- WaitHandle[]
Ein WaitHandle
-Array mit den Objekten, auf die die aktuelle Instanz wartet.
- millisecondsTimeout
- Int32
Die Anzahl von Millisekunden, die gewartet wird, oder Infinite (-1) für Warten ohne Timeout.
- exitContext
- Boolean
true
, um die Synchronisierungsdomäne für den Kontext vor dem Wartevorgang (sofern in einem synchronisierten Kontext) zu verlassen und diese anschließend erneut abzurufen, andernfalls false
.
Gibt zurück
Der Arrayindex des Objekts, das den Wartevorgang erfüllt hat, oder WaitTimeout, wenn keines der Objekte den Wartevorgang erfüllt hat und ein Zeitintervall äquivalent zu millisecondsTimeout
vergangen ist.
Ausnahmen
Der waitHandles
-Parameter ist null
.
- oder -
Mindestens ein Objekt im waitHandles
-Array ist null
.
Die Anzahl von Objekten in waitHandles
ist größer, als das System erlaubt.
waitHandles
ist ein Array ohne Elemente, und die .NET Framework-Version ist 1.0 oder 1.1.
millisecondsTimeout
ist eine negative Zahl, jedoch nicht -1, was einen unbeschränkten Timeout darstellt.
Der Wartevorgang wird abgeschlossen, weil ein Thread beendet wurde, ohne ein Mutex freizugeben.
waitHandles
ist ein Array ohne Elemente, und die .NET Framework-Version ist 2.0 oder höher.
Das waitHandles
-Array enthält einen transparenten Proxy für ein WaitHandle in einer anderen Anwendungsdomäne.
Beispiele
Im folgenden Codebeispiel wird veranschaulicht, wie Sie den Threadpool verwenden, um gleichzeitig auf mehreren Datenträgern nach einer Datei zu suchen. Aus Gründen des Speicherplatzes wird nur das Stammverzeichnis jedes Datenträgers durchsucht.
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
Hinweise
Wenn millisecondsTimeout
null ist, wird die -Methode nicht blockiert. Er testet den Status der Wartevorgänge und gibt sofort zurück.
Die WaitAny -Methode löst nur aus AbandonedMutexException , wenn die Wartezeit aufgrund eines abgebrochenen Mutex abgeschlossen ist. Wenn waitHandles
ein freigegebener Mutex mit einer niedrigeren Indexnummer als der verlassene Mutex enthält, wird die WaitAny Methode normal abgeschlossen, und die Ausnahme wird nicht ausgelöst. Ein aufgegebener Mutex weist häufig auf einen schwerwiegenden Codierungsfehler hin. Bei einem systemweiten Mutex kann dies darauf hindeuten, dass eine Anwendung abrupt beendet wurde (z. B. mithilfe des Windows Task-Managers). Die Ausnahme enthält Informationen, die für das Debuggen nützlich sind.
Diese Methode gibt zurück, wenn die Wartezeit beendet wird, entweder wenn eines der Handles signalisiert wird oder wenn ein Timeout auftritt. Wenn während des Aufrufs mehr als ein Objekt signalisiert wird, ist der Rückgabewert der Arrayindex des signalierten Objekts mit dem kleinsten Indexwert aller signalisierten Objekte.
Die maximale Anzahl der Wartehandles beträgt 64 und 63, wenn sich der aktuelle Thread im STA Zustand befindet.
Beenden des Kontexts
Der exitContext
-Parameter hat keine Auswirkung, es sei denn, diese Methode wird aus einem nicht standardmäßig verwalteten Kontext aufgerufen. Der verwaltete Kontext kann nicht standardmäßig sein, wenn sich Ihr Thread in einem Aufruf eines instance einer klasse befindet, die von ContextBoundObjectabgeleitet wird. Auch wenn Sie derzeit eine Methode für eine Klasse ausführen, die nicht von ContextBoundObjectabgeleitet ist, wie String, können Sie sich in einem nicht standardmäßigen Kontext befinden, wenn sich ein ContextBoundObject in Ihrem Stapel in der aktuellen Anwendungsdomäne befindet.
Wenn Ihr Code in einem nicht standardmäßigen Kontext ausgeführt wird, bewirkt die Angabe true
von für exitContext
, dass der Thread den nicht standardmäßig verwalteten Kontext beendet (d. h. zum Übergang in den Standardkontext), bevor diese Methode ausgeführt wird. Der Thread kehrt zum ursprünglichen nicht standardmäßigen Kontext zurück, nachdem der Aufruf dieser Methode abgeschlossen wurde.
Das Beenden des Kontexts kann nützlich sein, wenn die kontextgebundene Klasse über das SynchronizationAttribute -Attribut verfügt. In diesem Fall werden alle Aufrufe von Membern der -Klasse automatisch synchronisiert, und die Synchronisierungsdomäne ist der gesamte Codetext der Klasse. Wenn Code im Aufrufstapel eines Members diese Methode aufruft und für exitContext
angibttrue
, beendet der Thread die Synchronisierungsdomäne, sodass ein Thread, der bei einem Aufruf eines beliebigen Elements des -Objekts blockiert wird, fortfahren kann. Wenn diese Methode zurückgibt, muss der Thread, der den Aufruf ausgeführt hat, warten, um wieder in die Synchronisierungsdomäne zu wechseln.
Gilt für:
.NET 9 und andere Versionen
Produkt | Versionen |
---|---|
.NET | Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9 |
.NET Framework | 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1 |
.NET Standard | 2.0, 2.1 |
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
- Quelle:
- WaitHandle.cs
Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen, wobei ein TimeSpan zum Angeben des Zeitintervalls verwendet wird, und gibt an, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll.
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
Parameter
- waitHandles
- WaitHandle[]
Ein WaitHandle
-Array mit den Objekten, auf die die aktuelle Instanz wartet.
- timeout
- TimeSpan
Eine TimeSpan-Struktur, die die Anzahl der zu wartenden Millisekunden angibt, oder eine TimeSpan-Struktur, die -1 Millisekunden zum unendlichen Warten angibt.
- exitContext
- Boolean
true
, um die Synchronisierungsdomäne für den Kontext vor dem Wartevorgang (sofern in einem synchronisierten Kontext) zu verlassen und diese anschließend erneut abzurufen, andernfalls false
.
Gibt zurück
Der Arrayindex des Objekts, das den Wartevorgang erfüllt hat, oder WaitTimeout, wenn keines der Objekte den Wartevorgang erfüllt hat und ein Zeitintervall äquivalent zu timeout
vergangen ist.
Ausnahmen
Der waitHandles
-Parameter ist null
.
- oder -
Mindestens ein Objekt im waitHandles
-Array ist null
.
Die Anzahl von Objekten in waitHandles
ist größer, als das System erlaubt.
waitHandles
ist ein Array ohne Elemente, und die .NET Framework-Version ist 1.0 oder 1.1.
timeout
ist eine negative Zahl ungleich -1 Millisekunden, die ein unendliches Timeout darstellt.
- oder -
timeout
ist größer als Int32.MaxValue.
Der Wartevorgang wird abgeschlossen, weil ein Thread beendet wurde, ohne ein Mutex freizugeben.
waitHandles
ist ein Array ohne Elemente, und die .NET Framework-Version ist 2.0 oder höher.
Das waitHandles
-Array enthält einen transparenten Proxy für ein WaitHandle in einer anderen Anwendungsdomäne.
Beispiele
Im folgenden Codebeispiel wird veranschaulicht, wie Sie mit dem Threadpool gleichzeitig nach einer Datei auf mehreren Datenträgern suchen. Aus Speicherplatzgründen wird nur das Stammverzeichnis jedes Datenträgers durchsucht.
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
Hinweise
Wenn timeout
null ist, wird die -Methode nicht blockiert. Er testet den Zustand der Wartevorgänge und gibt sofort zurück.
Die WaitAny -Methode löst nur ein aus AbandonedMutexException , wenn die Wartezeit aufgrund eines abgebrochenen Mutex abgeschlossen ist. Wenn waitHandles
ein freigegebener Mutex mit einer niedrigeren Indexnummer als der verlassene Mutex enthält, wird die WaitAny Methode normal abgeschlossen, und die Ausnahme wird nicht ausgelöst. Ein aufgegebener Mutex weist häufig auf einen schwerwiegenden Codierungsfehler hin. Bei einem systemweiten Mutex kann dies darauf hindeuten, dass eine Anwendung abrupt beendet wurde (z. B. mithilfe des Windows Task-Managers). Die Ausnahme enthält Informationen, die für das Debuggen nützlich sind.
Diese Methode gibt zurück, wenn die Wartezeit beendet wird, entweder wenn eines der Handles signalisiert wird oder wenn ein Timeout auftritt. Wenn während des Aufrufs mehr als ein Objekt signalisiert wird, ist der Rückgabewert der Arrayindex des signalierten Objekts mit dem kleinsten Indexwert aller signalisierten Objekte.
Die maximale Anzahl der Wartehandles beträgt 64 und 63, wenn sich der aktuelle Thread im STA Zustand befindet.
Der Maximalwert für timeout
ist Int32.MaxValue.
Beenden des Kontexts
Der exitContext
-Parameter hat keine Auswirkung, es sei denn, diese Methode wird aus einem nicht standardmäßig verwalteten Kontext aufgerufen. Der verwaltete Kontext kann nicht standardmäßig sein, wenn sich Ihr Thread in einem Aufruf eines instance einer klasse befindet, die von ContextBoundObjectabgeleitet wird. Auch wenn Sie derzeit eine Methode für eine Klasse ausführen, die nicht von ContextBoundObjectabgeleitet ist, wie String, können Sie sich in einem nicht standardmäßigen Kontext befinden, wenn sich ein ContextBoundObject in Ihrem Stapel in der aktuellen Anwendungsdomäne befindet.
Wenn Ihr Code in einem nicht standardmäßigen Kontext ausgeführt wird, bewirkt die Angabe true
von für exitContext
, dass der Thread den nicht standardmäßig verwalteten Kontext beendet (d. h. zum Übergang in den Standardkontext), bevor diese Methode ausgeführt wird. Der Thread kehrt zum ursprünglichen nicht standardmäßigen Kontext zurück, nachdem der Aufruf dieser Methode abgeschlossen wurde.
Das Beenden des Kontexts kann nützlich sein, wenn die kontextgebundene Klasse über das SynchronizationAttribute -Attribut verfügt. In diesem Fall werden alle Aufrufe von Membern der -Klasse automatisch synchronisiert, und die Synchronisierungsdomäne ist der gesamte Codetext der Klasse. Wenn Code im Aufrufstapel eines Members diese Methode aufruft und für exitContext
angibttrue
, beendet der Thread die Synchronisierungsdomäne, sodass ein Thread, der bei einem Aufruf eines beliebigen Elements des -Objekts blockiert wird, fortfahren kann. Wenn diese Methode zurückgibt, muss der Thread, der den Aufruf ausgeführt hat, warten, um wieder in die Synchronisierungsdomäne zu wechseln.
Gilt für:
.NET 9 und andere Versionen
Produkt | Versionen |
---|---|
.NET | Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9 |
.NET Framework | 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1 |
.NET Standard | 2.0, 2.1 |
Feedback zu .NET
.NET ist ein Open Source-Projekt. Wählen Sie einen Link aus, um Feedback zu geben: