WaitHandle.WaitAny Metod
Definition
Viktigt
En del information gäller för förhandsversionen av en produkt och kan komma att ändras avsevärt innan produkten blir allmänt tillgänglig. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, avseende informationen som visas här.
Väntar på att något av elementen i den angivna matrisen ska ta emot en signal.
Överlagringar
| Name | Description |
|---|---|
| WaitAny(WaitHandle[]) |
Väntar på att något av elementen i den angivna matrisen ska ta emot en signal. |
| WaitAny(WaitHandle[], Int32) |
Väntar på att något av elementen i den angivna matrisen ska ta emot en signal med hjälp av ett 32-bitars signerat heltal för att ange tidsintervallet. |
| WaitAny(WaitHandle[], TimeSpan) |
Väntar på att något av elementen i den angivna matrisen ska ta emot en signal med hjälp av en TimeSpan för att ange tidsintervallet. |
| WaitAny(WaitHandle[], Int32, Boolean) |
Väntar på att något av elementen i den angivna matrisen ska ta emot en signal med hjälp av ett 32-bitars signerat heltal för att ange tidsintervallet och ange om synkroniseringsdomänen ska avslutas före väntan. |
| WaitAny(WaitHandle[], TimeSpan, Boolean) |
Väntar på att något av elementen i den angivna matrisen ska ta emot en signal, med hjälp av en TimeSpan för att ange tidsintervallet och ange om synkroniseringsdomänen ska avslutas före väntan. |
WaitAny(WaitHandle[])
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
Väntar på att något av elementen i den angivna matrisen ska ta emot en signal.
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
Parametrar
- waitHandles
- WaitHandle[]
En WaitHandle matris som innehåller de objekt som den aktuella instansen väntar på.
Returer
Matrisindexet för objektet som uppfyllde väntan.
Undantag
Parametern waitHandles är null.
-eller-
Ett eller flera av objekten i matrisen waitHandles är null.
Antalet objekt i waitHandles är större än vad systemet tillåter.
waitHandles är en matris utan element och .NET Framework-versionen är 1.0 eller 1.1.
Väntan slutfördes eftersom en tråd avslutades utan att en mutex släpptes.
waitHandles är en matris utan element och .NET Framework-versionen är 2.0 eller senare.
Matrisen waitHandles innehåller en transparent proxy för en i en WaitHandle annan programdomän.
Exempel
Följande kodexempel visar hur du anropar WaitAny metoden.
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).
Kommentarer
AbandonedMutexException är nytt i .NET Framework version 2.0. I tidigare versioner WaitAny returnerar true metoden om väntetiden slutförs eftersom en mutex avbryts. Ett övergivet mutex indikerar ofta ett allvarligt kodfel. När det gäller en systemomfattande mutex kan det tyda på att ett program har avslutats plötsligt (till exempel med hjälp av Windows Aktivitetshanteraren). Undantaget innehåller information som är användbar för felsökning.
Metoden WaitAny genererar endast när AbandonedMutexException väntan slutförs på grund av en övergiven mutex. Om waitHandles innehåller en utgiven mutex med ett lägre indexnummer än den övergivna mutexen WaitAny slutförs metoden normalt och undantaget genereras inte.
Note
I versioner av .NET Framework tidigare än version 2.0, om en tråd avslutas eller avbryts utan att uttryckligen släppa en Mutex, och att Mutex är vid index 0 (noll) i en WaitAny matris i en annan tråd, är indexet som returneras av WaitAny 128 i stället för 0.
Den här metoden returnerar när alla referenser signaleras. Om fler än ett objekt signaleras under anropet är returvärdet matrisindexet för det signalerade objektet med det minsta indexvärdet för alla signalerade objekt.
Det maximala antalet väntehandtag är 64 och 63 om den aktuella tråden är i STA tillstånd.
Att anropa den här metodens överlagring motsvarar att anropa WaitAny(WaitHandle[], Int32, Boolean) metodens överlagring och ange -1 (eller Timeout.Infinite) för millisecondsTimeout och true för exitContext.
Gäller för
WaitAny(WaitHandle[], Int32)
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
Väntar på att något av elementen i den angivna matrisen ska ta emot en signal med hjälp av ett 32-bitars signerat heltal för att ange tidsintervallet.
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
Parametrar
- waitHandles
- WaitHandle[]
En WaitHandle matris som innehåller de objekt som den aktuella instansen väntar på.
- millisecondsTimeout
- Int32
Antalet millisekunder som ska vänta eller Infinite (-1) för att vänta på obestämd tid.
Returer
Matrisindexet för objektet som uppfyllde väntetiden, eller WaitTimeout om inget objekt uppfyllde väntetiden och ett tidsintervall som motsvarar millisecondsTimeout har passerat.
Undantag
Parametern waitHandles är null.
-eller-
Ett eller flera av objekten i matrisen waitHandles är null.
Antalet objekt i waitHandles är större än vad systemet tillåter.
millisecondsTimeout är ett annat negativt tal än -1, vilket representerar en oändlig timeout.
Väntan slutfördes eftersom en tråd avslutades utan att en mutex släpptes.
waitHandles är en matris utan element.
Matrisen waitHandles innehåller en transparent proxy för en i en WaitHandle annan programdomän.
Kommentarer
Om millisecondsTimeout är noll blockeras inte metoden. Den testar tillståndet för väntehandtagen och returnerar omedelbart.
Metoden WaitAny genererar endast när AbandonedMutexException väntan slutförs på grund av en övergiven mutex. Om waitHandles innehåller en utgiven mutex med ett lägre indexnummer än den övergivna mutexen WaitAny slutförs metoden normalt och undantaget genereras inte.
Den här metoden returnerar när väntetiden avslutas, antingen när något av handtagen signaleras eller när tidsgränsen uppnås. Om fler än ett objekt signaleras under anropet är returvärdet matrisindexet för det signalerade objektet med det minsta indexvärdet för alla signalerade objekt.
Det maximala antalet väntehandtag är 64 och 63 om den aktuella tråden är i STA tillstånd.
Att anropa den här metodens överlagring är detsamma som att anropa överlagringen WaitAny(WaitHandle[], Int32, Boolean) och ange false för exitContext.
Gäller för
WaitAny(WaitHandle[], TimeSpan)
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
Väntar på att något av elementen i den angivna matrisen ska ta emot en signal med hjälp av en TimeSpan för att ange tidsintervallet.
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
Parametrar
- waitHandles
- WaitHandle[]
En WaitHandle matris som innehåller de objekt som den aktuella instansen väntar på.
- timeout
- TimeSpan
En TimeSpan som representerar antalet millisekunder som ska vänta, eller ett TimeSpan som representerar -1 millisekunder för att vänta på obestämd tid.
Returer
Matrisindexet för objektet som uppfyllde väntetiden, eller WaitTimeout om inget objekt uppfyllde väntetiden och ett tidsintervall som motsvarar timeout har passerat.
Undantag
Parametern waitHandles är null.
-eller-
Ett eller flera av objekten i matrisen waitHandles är null.
Antalet objekt i waitHandles är större än vad systemet tillåter.
timeout är ett annat negativt tal än -1 millisekunder, vilket representerar en oändlig timeout.
-eller-
timeout är större än Int32.MaxValue.
Väntan slutfördes eftersom en tråd avslutades utan att en mutex släpptes.
waitHandles är en matris utan element.
Matrisen waitHandles innehåller en transparent proxy för en i en WaitHandle annan programdomän.
Kommentarer
Om timeout är noll blockeras inte metoden. Den testar tillståndet för väntehandtagen och returnerar omedelbart.
Metoden WaitAny genererar endast när AbandonedMutexException väntan slutförs på grund av en övergiven mutex. Om waitHandles innehåller en utgiven mutex med ett lägre indexnummer än den övergivna mutexen WaitAny slutförs metoden normalt och undantaget genereras inte.
Den här metoden returnerar när väntetiden avslutas, antingen när något av handtagen signaleras eller när tidsgränsen uppnås. Om fler än ett objekt signaleras under anropet är returvärdet matrisindexet för det signalerade objektet med det minsta indexvärdet för alla signalerade objekt.
Det maximala antalet väntehandtag är 64 och 63 om den aktuella tråden är i STA tillstånd.
Det maximala värdet för timeout är Int32.MaxValue.
Att anropa den här metodens överlagring är detsamma som att anropa överlagringen WaitAny(WaitHandle[], TimeSpan, Boolean) och ange false för exitContext.
Gäller för
WaitAny(WaitHandle[], Int32, Boolean)
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
Väntar på att något av elementen i den angivna matrisen ska ta emot en signal med hjälp av ett 32-bitars signerat heltal för att ange tidsintervallet och ange om synkroniseringsdomänen ska avslutas före väntan.
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
Parametrar
- waitHandles
- WaitHandle[]
En WaitHandle matris som innehåller de objekt som den aktuella instansen väntar på.
- millisecondsTimeout
- Int32
Antalet millisekunder som ska vänta eller Infinite (-1) för att vänta på obestämd tid.
- exitContext
- Boolean
trueför att avsluta synkroniseringsdomänen för kontexten före väntan (om i en synkroniserad kontext) och återkräv den efteråt. annars . false
Returer
Matrisindexet för objektet som uppfyllde väntetiden, eller WaitTimeout om inget objekt uppfyllde väntetiden och ett tidsintervall som motsvarar millisecondsTimeout har passerat.
Undantag
Parametern waitHandles är null.
-eller-
Ett eller flera av objekten i matrisen waitHandles är null.
Antalet objekt i waitHandles är större än vad systemet tillåter.
waitHandles är en matris utan element och .NET Framework-versionen är 1.0 eller 1.1.
millisecondsTimeout är ett annat negativt tal än -1, vilket representerar en oändlig timeout.
Väntan slutfördes eftersom en tråd avslutades utan att en mutex släpptes.
waitHandles är en matris utan element och .NET Framework-versionen är 2.0 eller senare.
Matrisen waitHandles innehåller en transparent proxy för en i en WaitHandle annan programdomän.
Exempel
Följande kodexempel visar hur du använder trådpoolen för att samtidigt söka efter en fil på flera diskar. För utrymmesöverväganden genomsöks endast rotkatalogen för varje disk.
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
Kommentarer
Om millisecondsTimeout är noll blockeras inte metoden. Den testar tillståndet för väntehandtagen och returnerar omedelbart.
Metoden WaitAny genererar endast när AbandonedMutexException väntan slutförs på grund av en övergiven mutex. Om waitHandles innehåller en utgiven mutex med ett lägre indexnummer än den övergivna mutexen WaitAny slutförs metoden normalt och undantaget genereras inte. Ett övergivet mutex indikerar ofta ett allvarligt kodfel. När det gäller en systemomfattande mutex kan det tyda på att ett program har avslutats plötsligt (till exempel med hjälp av Windows Aktivitetshanteraren). Undantaget innehåller information som är användbar för felsökning.
Den här metoden returnerar när väntetiden avslutas, antingen när något av handtagen signaleras eller när tidsgränsen uppnås. Om fler än ett objekt signaleras under anropet är returvärdet matrisindexet för det signalerade objektet med det minsta indexvärdet för alla signalerade objekt.
Det maximala antalet väntehandtag är 64 och 63 om den aktuella tråden är i STA tillstånd.
Avsluta kontexten
Parametern exitContext har ingen effekt om inte den här metoden anropas inifrån en nondefault-hanterad kontext. Den hanterade kontexten kan vara nondefault om tråden finns i ett anrop till en instans av en klass som härletts från ContextBoundObject. Även om du för närvarande kör en metod på en klass som inte härleds från ContextBoundObject, till exempel String, kan du vara i en nondefault-kontext om en ContextBoundObject finns på stacken i den aktuella programdomänen.
När koden körs i en nondefault-kontext anger du true för exitContext att tråden ska avsluta den nondefault-hanterade kontexten (dvs. att övergå till standardkontexten) innan den här metoden körs. Tråden återgår till den ursprungliga nondefault-kontexten när anropet till den här metoden har slutförts.
Det kan vara användbart att avsluta kontexten när den kontextbundna klassen har attributet SynchronizationAttribute . I så fall synkroniseras alla anrop till medlemmar i klassen automatiskt och synkroniseringsdomänen är hela kodtexten för klassen. Om kod i anropsstacken för en medlem anropar true den här metoden och anger för exitContextavslutar tråden synkroniseringsdomänen, vilket gör att en tråd som blockeras vid ett anrop till alla medlemmar i objektet kan fortsätta. När den här metoden returneras måste tråden som gjorde anropet vänta tills synkroniseringsdomänen har återaktiviserats.
Gäller för
WaitAny(WaitHandle[], TimeSpan, Boolean)
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
- Källa:
- WaitHandle.cs
Väntar på att något av elementen i den angivna matrisen ska ta emot en signal, med hjälp av en TimeSpan för att ange tidsintervallet och ange om synkroniseringsdomänen ska avslutas före väntan.
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
Parametrar
- waitHandles
- WaitHandle[]
En WaitHandle matris som innehåller de objekt som den aktuella instansen väntar på.
- timeout
- TimeSpan
En TimeSpan som representerar antalet millisekunder som ska vänta, eller ett TimeSpan som representerar -1 millisekunder för att vänta på obestämd tid.
- exitContext
- Boolean
trueför att avsluta synkroniseringsdomänen för kontexten före väntan (om i en synkroniserad kontext) och återkräv den efteråt. annars . false
Returer
Matrisindexet för objektet som uppfyllde väntetiden, eller WaitTimeout om inget objekt uppfyllde väntetiden och ett tidsintervall som motsvarar timeout har passerat.
Undantag
Parametern waitHandles är null.
-eller-
Ett eller flera av objekten i matrisen waitHandles är null.
Antalet objekt i waitHandles är större än vad systemet tillåter.
waitHandles är en matris utan element och .NET Framework-versionen är 1.0 eller 1.1.
timeout är ett annat negativt tal än -1 millisekunder, vilket representerar en oändlig timeout.
-eller-
timeout är större än Int32.MaxValue.
Väntan slutfördes eftersom en tråd avslutades utan att en mutex släpptes.
waitHandles är en matris utan element och .NET Framework-versionen är 2.0 eller senare.
Matrisen waitHandles innehåller en transparent proxy för en i en WaitHandle annan programdomän.
Exempel
Följande kodexempel visar hur du använder trådpoolen för att samtidigt söka efter en fil på flera diskar. För utrymmesöverväganden genomsöks endast rotkatalogen för varje disk.
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
Kommentarer
Om timeout är noll blockeras inte metoden. Den testar tillståndet för väntehandtagen och returnerar omedelbart.
Metoden WaitAny genererar endast när AbandonedMutexException väntan slutförs på grund av en övergiven mutex. Om waitHandles innehåller en utgiven mutex med ett lägre indexnummer än den övergivna mutexen WaitAny slutförs metoden normalt och undantaget genereras inte. Ett övergivet mutex indikerar ofta ett allvarligt kodfel. När det gäller en systemomfattande mutex kan det tyda på att ett program har avslutats plötsligt (till exempel med hjälp av Windows Aktivitetshanteraren). Undantaget innehåller information som är användbar för felsökning.
Den här metoden returnerar när väntetiden avslutas, antingen när något av handtagen signaleras eller när tidsgränsen uppnås. Om fler än ett objekt signaleras under anropet är returvärdet matrisindexet för det signalerade objektet med det minsta indexvärdet för alla signalerade objekt.
Det maximala antalet väntehandtag är 64 och 63 om den aktuella tråden är i STA tillstånd.
Det maximala värdet för timeout är Int32.MaxValue.
Avsluta kontexten
Parametern exitContext har ingen effekt om inte den här metoden anropas inifrån en nondefault-hanterad kontext. Den hanterade kontexten kan vara nondefault om tråden finns i ett anrop till en instans av en klass som härletts från ContextBoundObject. Även om du för närvarande kör en metod på en klass som inte härleds från ContextBoundObject, till exempel String, kan du vara i en nondefault-kontext om en ContextBoundObject finns på stacken i den aktuella programdomänen.
När koden körs i en nondefault-kontext anger du true för exitContext att tråden ska avsluta den nondefault-hanterade kontexten (dvs. att övergå till standardkontexten) innan den här metoden körs. Tråden återgår till den ursprungliga nondefault-kontexten när anropet till den här metoden har slutförts.
Det kan vara användbart att avsluta kontexten när den kontextbundna klassen har attributet SynchronizationAttribute . I så fall synkroniseras alla anrop till medlemmar i klassen automatiskt och synkroniseringsdomänen är hela kodtexten för klassen. Om kod i anropsstacken för en medlem anropar true den här metoden och anger för exitContextavslutar tråden synkroniseringsdomänen, vilket gör att en tråd som blockeras vid ett anrop till alla medlemmar i objektet kan fortsätta. När den här metoden returneras måste tråden som gjorde anropet vänta tills synkroniseringsdomänen har återaktiviserats.