WaitHandle.WaitAny Methode
Definitie
Belangrijk
Bepaalde informatie heeft betrekking op een voorlopige productversie die aanzienlijk kan worden gewijzigd voordat deze wordt uitgebracht. Microsoft biedt geen enkele expliciete of impliciete garanties met betrekking tot de informatie die hier wordt verstrekt.
Wacht tot een van de elementen in de opgegeven matrix een signaal ontvangt.
Overloads
| Name | Description |
|---|---|
| WaitAny(WaitHandle[]) |
Wacht tot een van de elementen in de opgegeven matrix een signaal ontvangt. |
| WaitAny(WaitHandle[], Int32) |
Wacht tot een van de elementen in de opgegeven matrix een signaal ontvangt met behulp van een 32-bits ondertekend geheel getal om het tijdsinterval op te geven. |
| WaitAny(WaitHandle[], TimeSpan) |
Wacht tot een van de elementen in de opgegeven matrix een signaal ontvangt, met behulp van een TimeSpan om het tijdsinterval op te geven. |
| WaitAny(WaitHandle[], Int32, Boolean) |
Wacht tot een van de elementen in de opgegeven matrix een signaal ontvangt, met behulp van een 32-bits geheel getal dat is ondertekend om het tijdsinterval op te geven en op te geven of het synchronisatiedomein moet worden afgesloten voordat de wacht wordt uitgevoerd. |
| WaitAny(WaitHandle[], TimeSpan, Boolean) |
Wacht tot een van de elementen in de opgegeven matrix een signaal ontvangt, met behulp van een TimeSpan om het tijdsinterval op te geven en op te geven of het synchronisatiedomein moet worden afgesloten voordat de wachttijd wordt uitgevoerd. |
WaitAny(WaitHandle[])
Wacht tot een van de elementen in de opgegeven matrix een signaal ontvangt.
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
Parameters
- waitHandles
- WaitHandle[]
Een WaitHandle matrix met de objecten waarvoor het huidige exemplaar wacht.
Retouren
De matrixindex van het object dat voldeed aan de wachttijd.
Uitzonderingen
De waitHandles parameter is null.
– of –
Een of meer van de objecten in de waitHandles matrix is null.
Het aantal objecten in waitHandles is groter dan het systeem toestaat.
waitHandles is een matrix zonder elementen en de .NET Framework-versie is 1.0 of 1.1.
De wachttijd is voltooid omdat een thread is afgesloten zonder een mutex vrij te geven.
waitHandles is een matrix zonder elementen en de .NET Framework-versie is 2.0 of hoger.
De waitHandles matrix bevat een transparante proxy voor een in een WaitHandle ander toepassingsdomein.
Voorbeelden
In het volgende codevoorbeeld ziet u hoe u de WaitAny methode aanroept.
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).
Opmerkingen
AbandonedMutexException is nieuw in de .NET Framework-versie 2.0. In eerdere versies retourneert true de WaitAny methode als de wachttijd is voltooid omdat een mutex wordt afgelaten. Een verlaten mutex duidt vaak op een ernstige coderingsfout. In het geval van een systeembrede mutex kan dit erop wijzen dat een toepassing plotseling is beëindigd (bijvoorbeeld met behulp van Windows Taakbeheer). De uitzondering bevat informatie die nuttig is voor foutopsporing.
De WaitAny methode genereert een AbandonedMutexException alleen wanneer de wachttijd is voltooid vanwege een verlaten mutex. Als waitHandles er een uitgebrachte mutex met een lager indexnummer dan de verlaten mutex bevat, wordt de WaitAny methode normaal voltooid en wordt de uitzondering niet gegenereerd.
Note
In versies van het .NET Framework ouder dan versie 2.0, als een thread wordt afgesloten of afgebroken zonder expliciet een Mutex uit te brengen en dat Mutex zich op index 0 (nul) bevindt in een WaitAny matrix op een andere thread, is de index die wordt geretourneerd door WaitAny 128 in plaats van 0.
Deze methode retourneert wanneer een greep wordt gesignaleerd. Als er meer dan één object wordt gesignaleerd tijdens de aanroep, is de retourwaarde de matrixindex van het gesignaleerde object met de kleinste indexwaarde van alle gesignaleerde objecten.
Het maximum aantal wachtgrepen is 64 en 63 als de huidige thread de status heeft STA .
Het aanroepen van deze methode-overbelasting is gelijk aan het aanroepen van de WaitAny(WaitHandle[], Int32, Boolean) methode-overbelasting en het opgeven van -1 (of Timeout.Infinite) voor millisecondsTimeout en true voor exitContext.
Van toepassing op
WaitAny(WaitHandle[], Int32)
Wacht tot een van de elementen in de opgegeven matrix een signaal ontvangt met behulp van een 32-bits ondertekend geheel getal om het tijdsinterval op te geven.
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
Parameters
- waitHandles
- WaitHandle[]
Een WaitHandle matrix met de objecten waarvoor het huidige exemplaar wacht.
- millisecondsTimeout
- Int32
Het aantal milliseconden dat moet worden gewacht, of Infinite (-1) om voor onbepaalde tijd te wachten.
Retouren
De matrixindex van het object dat voldeed aan de wachttijd of WaitTimeout als er geen object voldeed aan de wachttijd en een tijdsinterval dat gelijk is aan millisecondsTimeout is verstreken.
Uitzonderingen
De waitHandles parameter is null.
– of –
Een of meer van de objecten in de waitHandles matrix is null.
Het aantal objecten in waitHandles is groter dan het systeem toestaat.
millisecondsTimeout is een ander negatief getal dan -1, dat een oneindige time-out vertegenwoordigt.
De wachttijd is voltooid omdat een thread is afgesloten zonder een mutex vrij te geven.
waitHandles is een matrix zonder elementen.
De waitHandles matrix bevat een transparante proxy voor een in een WaitHandle ander toepassingsdomein.
Opmerkingen
Als millisecondsTimeout nul is, wordt de methode niet geblokkeerd. Hiermee wordt de status van de wachtgrepen getest en onmiddellijk geretourneerd.
De WaitAny methode genereert een AbandonedMutexException alleen wanneer de wachttijd is voltooid vanwege een verlaten mutex. Als waitHandles er een uitgebrachte mutex met een lager indexnummer dan de verlaten mutex bevat, wordt de WaitAny methode normaal voltooid en wordt de uitzondering niet gegenereerd.
Deze methode retourneert wanneer de wachttijd wordt beëindigd, hetzij wanneer een van de ingangen wordt gesignaleerd of wanneer er een time-out optreedt. Als er meer dan één object wordt gesignaleerd tijdens de aanroep, is de retourwaarde de matrixindex van het gesignaleerde object met de kleinste indexwaarde van alle gesignaleerde objecten.
Het maximum aantal wachtgrepen is 64 en 63 als de huidige thread de status heeft STA .
Het aanroepen van deze methode-overbelasting is hetzelfde als het aanroepen van de WaitAny(WaitHandle[], Int32, Boolean) overbelasting en het opgeven voor falseexitContext.
Van toepassing op
WaitAny(WaitHandle[], TimeSpan)
Wacht tot een van de elementen in de opgegeven matrix een signaal ontvangt, met behulp van een TimeSpan om het tijdsinterval op te geven.
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
Parameters
- waitHandles
- WaitHandle[]
Een WaitHandle matrix met de objecten waarvoor het huidige exemplaar wacht.
- timeout
- TimeSpan
Een TimeSpan die het aantal milliseconden aangeeft dat moet worden gewacht, of een TimeSpan waarde die -1 milliseconden vertegenwoordigt om voor onbepaalde tijd te wachten.
Retouren
De matrixindex van het object dat voldeed aan de wachttijd of WaitTimeout als er geen object voldeed aan de wachttijd en een tijdsinterval dat gelijk is aan timeout is verstreken.
Uitzonderingen
De waitHandles parameter is null.
– of –
Een of meer van de objecten in de waitHandles matrix is null.
Het aantal objecten in waitHandles is groter dan het systeem toestaat.
timeout is een ander negatief getal dan -1 milliseconden, wat een oneindige time-out vertegenwoordigt.
– of –
timeout is groter dan Int32.MaxValue.
De wachttijd is voltooid omdat een thread is afgesloten zonder een mutex vrij te geven.
waitHandles is een matrix zonder elementen.
De waitHandles matrix bevat een transparante proxy voor een in een WaitHandle ander toepassingsdomein.
Opmerkingen
Als timeout nul is, wordt de methode niet geblokkeerd. Hiermee wordt de status van de wachtgrepen getest en onmiddellijk geretourneerd.
De WaitAny methode genereert een AbandonedMutexException alleen wanneer de wachttijd is voltooid vanwege een verlaten mutex. Als waitHandles er een uitgebrachte mutex met een lager indexnummer dan de verlaten mutex bevat, wordt de WaitAny methode normaal voltooid en wordt de uitzondering niet gegenereerd.
Deze methode retourneert wanneer de wachttijd wordt beëindigd, hetzij wanneer een van de ingangen wordt gesignaleerd of wanneer er een time-out optreedt. Als er meer dan één object wordt gesignaleerd tijdens de aanroep, is de retourwaarde de matrixindex van het gesignaleerde object met de kleinste indexwaarde van alle gesignaleerde objecten.
Het maximum aantal wachtgrepen is 64 en 63 als de huidige thread de status heeft STA .
De maximumwaarde voor timeout is Int32.MaxValue.
Het aanroepen van deze methode-overbelasting is hetzelfde als het aanroepen van de WaitAny(WaitHandle[], TimeSpan, Boolean) overbelasting en het opgeven voor falseexitContext.
Van toepassing op
WaitAny(WaitHandle[], Int32, Boolean)
Wacht tot een van de elementen in de opgegeven matrix een signaal ontvangt, met behulp van een 32-bits geheel getal dat is ondertekend om het tijdsinterval op te geven en op te geven of het synchronisatiedomein moet worden afgesloten voordat de wacht wordt uitgevoerd.
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
Parameters
- waitHandles
- WaitHandle[]
Een WaitHandle matrix met de objecten waarvoor het huidige exemplaar wacht.
- millisecondsTimeout
- Int32
Het aantal milliseconden dat moet worden gewacht, of Infinite (-1) om voor onbepaalde tijd te wachten.
- exitContext
- Boolean
true om het synchronisatiedomein voor de context vóór de wachttijd af te sluiten (indien in een gesynchroniseerde context) en het daarna opnieuw te vragen; anders, false.
Retouren
De matrixindex van het object dat voldeed aan de wachttijd of WaitTimeout als er geen object voldeed aan de wachttijd en een tijdsinterval dat gelijk is aan millisecondsTimeout is verstreken.
Uitzonderingen
De waitHandles parameter is null.
– of –
Een of meer van de objecten in de waitHandles matrix is null.
Het aantal objecten in waitHandles is groter dan het systeem toestaat.
waitHandles is een matrix zonder elementen en de .NET Framework-versie is 1.0 of 1.1.
millisecondsTimeout is een ander negatief getal dan -1, dat een oneindige time-out vertegenwoordigt.
De wachttijd is voltooid omdat een thread is afgesloten zonder een mutex vrij te geven.
waitHandles is een matrix zonder elementen en de .NET Framework-versie is 2.0 of hoger.
De waitHandles matrix bevat een transparante proxy voor een in een WaitHandle ander toepassingsdomein.
Voorbeelden
In het volgende codevoorbeeld ziet u hoe u de threadgroep gebruikt om tegelijkertijd te zoeken naar een bestand op meerdere schijven. Voor ruimteoverwegingen wordt alleen de hoofdmap van elke schijf doorzocht.
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
Opmerkingen
Als millisecondsTimeout nul is, wordt de methode niet geblokkeerd. Hiermee wordt de status van de wachtgrepen getest en onmiddellijk geretourneerd.
De WaitAny methode genereert een AbandonedMutexException alleen wanneer de wachttijd is voltooid vanwege een verlaten mutex. Als waitHandles er een uitgebrachte mutex met een lager indexnummer dan de verlaten mutex bevat, wordt de WaitAny methode normaal voltooid en wordt de uitzondering niet gegenereerd. Een verlaten mutex duidt vaak op een ernstige coderingsfout. In het geval van een systeembrede mutex kan dit erop wijzen dat een toepassing plotseling is beëindigd (bijvoorbeeld met behulp van Windows Taakbeheer). De uitzondering bevat informatie die nuttig is voor foutopsporing.
Deze methode retourneert wanneer de wachttijd wordt beëindigd, hetzij wanneer een van de ingangen wordt gesignaleerd of wanneer er een time-out optreedt. Als er meer dan één object wordt gesignaleerd tijdens de aanroep, is de retourwaarde de matrixindex van het gesignaleerde object met de kleinste indexwaarde van alle gesignaleerde objecten.
Het maximum aantal wachtgrepen is 64 en 63 als de huidige thread de status heeft STA .
De context afsluiten
De exitContext parameter heeft geen effect, tenzij deze methode wordt aangeroepen vanuit een niet-standaard beheerde context. De beheerde context kan niet-standaard zijn als uw thread zich in een aanroep bevindt naar een exemplaar van een klasse die is afgeleid van ContextBoundObject. Zelfs als u momenteel een methode uitvoert op een klasse die niet is afgeleid van ContextBoundObject, zoals String, kunt u zich in een niet-standaardcontext bevinden als een ContextBoundObject is op uw stack in het huidige toepassingsdomein.
Wanneer uw code wordt uitgevoerd in een niet-standaardcontext, geeft trueexitContext u aan dat de thread de niet-standaard beheerde context verlaat (dat wil gezegd, om over te stappen op de standaardcontext) voordat deze methode wordt uitgevoerd. De thread keert terug naar de oorspronkelijke niet-standaardcontext nadat de aanroep van deze methode is voltooid.
Het afsluiten van de context kan handig zijn wanneer de contextgebonden klasse het SynchronizationAttribute kenmerk heeft. In dat geval worden alle aanroepen naar leden van de klasse automatisch gesynchroniseerd en is het synchronisatiedomein de volledige hoofdtekst van de code voor de klasse. Als code in de aanroepstack van een lid deze methode aanroept en opgeeft trueexitContext, sluit de thread het synchronisatiedomein af, waardoor een thread die wordt geblokkeerd voor een aanroep naar een lid van het object, wordt voortgezet. Wanneer deze methode wordt geretourneerd, moet de thread die de aanroep heeft gedaan wachten om het synchronisatiedomein opnieuw in te voeren.
Van toepassing op
WaitAny(WaitHandle[], TimeSpan, Boolean)
Wacht tot een van de elementen in de opgegeven matrix een signaal ontvangt, met behulp van een TimeSpan om het tijdsinterval op te geven en op te geven of het synchronisatiedomein moet worden afgesloten voordat de wachttijd wordt uitgevoerd.
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
Parameters
- waitHandles
- WaitHandle[]
Een WaitHandle matrix met de objecten waarvoor het huidige exemplaar wacht.
- timeout
- TimeSpan
Een TimeSpan die het aantal milliseconden aangeeft dat moet worden gewacht, of een TimeSpan waarde die -1 milliseconden vertegenwoordigt om voor onbepaalde tijd te wachten.
- exitContext
- Boolean
true om het synchronisatiedomein voor de context vóór de wachttijd af te sluiten (indien in een gesynchroniseerde context) en het daarna opnieuw te vragen; anders, false.
Retouren
De matrixindex van het object dat voldeed aan de wachttijd of WaitTimeout als er geen object voldeed aan de wachttijd en een tijdsinterval dat gelijk is aan timeout is verstreken.
Uitzonderingen
De waitHandles parameter is null.
– of –
Een of meer van de objecten in de waitHandles matrix is null.
Het aantal objecten in waitHandles is groter dan het systeem toestaat.
waitHandles is een matrix zonder elementen en de .NET Framework-versie is 1.0 of 1.1.
timeout is een ander negatief getal dan -1 milliseconden, wat een oneindige time-out vertegenwoordigt.
– of –
timeout is groter dan Int32.MaxValue.
De wachttijd is voltooid omdat een thread is afgesloten zonder een mutex vrij te geven.
waitHandles is een matrix zonder elementen en de .NET Framework-versie is 2.0 of hoger.
De waitHandles matrix bevat een transparante proxy voor een in een WaitHandle ander toepassingsdomein.
Voorbeelden
In het volgende codevoorbeeld ziet u hoe u de threadgroep gebruikt om tegelijkertijd te zoeken naar een bestand op meerdere schijven. Voor ruimteoverwegingen wordt alleen de hoofdmap van elke schijf doorzocht.
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
Opmerkingen
Als timeout nul is, wordt de methode niet geblokkeerd. Hiermee wordt de status van de wachtgrepen getest en onmiddellijk geretourneerd.
De WaitAny methode genereert een AbandonedMutexException alleen wanneer de wachttijd is voltooid vanwege een verlaten mutex. Als waitHandles er een uitgebrachte mutex met een lager indexnummer dan de verlaten mutex bevat, wordt de WaitAny methode normaal voltooid en wordt de uitzondering niet gegenereerd. Een verlaten mutex duidt vaak op een ernstige coderingsfout. In het geval van een systeembrede mutex kan dit erop wijzen dat een toepassing plotseling is beëindigd (bijvoorbeeld met behulp van Windows Taakbeheer). De uitzondering bevat informatie die nuttig is voor foutopsporing.
Deze methode retourneert wanneer de wachttijd wordt beëindigd, hetzij wanneer een van de ingangen wordt gesignaleerd of wanneer er een time-out optreedt. Als er meer dan één object wordt gesignaleerd tijdens de aanroep, is de retourwaarde de matrixindex van het gesignaleerde object met de kleinste indexwaarde van alle gesignaleerde objecten.
Het maximum aantal wachtgrepen is 64 en 63 als de huidige thread de status heeft STA .
De maximumwaarde voor timeout is Int32.MaxValue.
De context afsluiten
De exitContext parameter heeft geen effect, tenzij deze methode wordt aangeroepen vanuit een niet-standaard beheerde context. De beheerde context kan niet-standaard zijn als uw thread zich in een aanroep bevindt naar een exemplaar van een klasse die is afgeleid van ContextBoundObject. Zelfs als u momenteel een methode uitvoert op een klasse die niet is afgeleid van ContextBoundObject, zoals String, kunt u zich in een niet-standaardcontext bevinden als een ContextBoundObject is op uw stack in het huidige toepassingsdomein.
Wanneer uw code wordt uitgevoerd in een niet-standaardcontext, geeft trueexitContext u aan dat de thread de niet-standaard beheerde context verlaat (dat wil gezegd, om over te stappen op de standaardcontext) voordat deze methode wordt uitgevoerd. De thread keert terug naar de oorspronkelijke niet-standaardcontext nadat de aanroep van deze methode is voltooid.
Het afsluiten van de context kan handig zijn wanneer de contextgebonden klasse het SynchronizationAttribute kenmerk heeft. In dat geval worden alle aanroepen naar leden van de klasse automatisch gesynchroniseerd en is het synchronisatiedomein de volledige hoofdtekst van de code voor de klasse. Als code in de aanroepstack van een lid deze methode aanroept en opgeeft trueexitContext, sluit de thread het synchronisatiedomein af, waardoor een thread die wordt geblokkeerd voor een aanroep naar een lid van het object, wordt voortgezet. Wanneer deze methode wordt geretourneerd, moet de thread die de aanroep heeft gedaan wachten om het synchronisatiedomein opnieuw in te voeren.