WaitHandle.WaitOne Metoda
Definicja
Ważne
Niektóre informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany przed wydaniem. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Blokuje bieżący wątek, dopóki bieżący WaitHandle nie otrzyma sygnału.
Przeciążenia
WaitOne() |
Blokuje bieżący wątek, dopóki bieżący WaitHandle nie otrzyma sygnału. |
WaitOne(Int32) |
Blokuje bieżący wątek do WaitHandle momentu odebrania sygnału przy użyciu 32-bitowej liczby całkowitej podpisanej w celu określenia interwału czasu w milisekundach. |
WaitOne(TimeSpan) |
Blokuje bieżący wątek, dopóki bieżące wystąpienie nie otrzyma sygnału przy użyciu elementu , TimeSpan aby określić interwał czasu. |
WaitOne(Int32, Boolean) |
Blokuje bieżący wątek do WaitHandle momentu odebrania sygnału przy użyciu 32-bitowej liczby całkowitej podpisanej w celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem. |
WaitOne(TimeSpan, Boolean) |
Blokuje bieżący wątek, dopóki bieżące wystąpienie nie otrzyma sygnału, przy użyciu elementu , TimeSpan aby określić interwał czasu i określić, czy należy zamknąć domenę synchronizacji przed oczekiwaniem. |
WaitOne()
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
Blokuje bieżący wątek, dopóki bieżący WaitHandle nie otrzyma sygnału.
public:
virtual bool WaitOne();
public virtual bool WaitOne ();
abstract member WaitOne : unit -> bool
override this.WaitOne : unit -> bool
Public Overridable Function WaitOne () As Boolean
Zwraca
true
jeśli bieżące wystąpienie odbiera sygnał. Jeśli bieżące wystąpienie nigdy nie zostanie zasygnalizowane, WaitOne() nigdy nie zostanie zwrócone.
Wyjątki
Bieżące wystąpienie zostało już usunięte.
Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.
Bieżące wystąpienie jest przezroczystym serwerem proxy dla WaitHandle innej domeny aplikacji.
Przykłady
W poniższym przykładzie kodu pokazano, jak użyć uchwytu oczekiwania, aby zatrzymać proces podczas oczekiwania na zakończenie wykonywania wątku w tle.
using namespace System;
using namespace System::Threading;
ref class WaitOne
{
private:
WaitOne(){}
public:
static void WorkMethod( Object^ stateInfo )
{
Console::WriteLine( "Work starting." );
// Simulate time spent working.
Thread::Sleep( (gcnew Random)->Next( 100, 2000 ) );
// Signal that work is finished.
Console::WriteLine( "Work ending." );
dynamic_cast<AutoResetEvent^>(stateInfo)->Set();
}
};
int main()
{
Console::WriteLine( "Main starting." );
AutoResetEvent^ autoEvent = gcnew AutoResetEvent( false );
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &WaitOne::WorkMethod ), autoEvent );
// Wait for work method to signal.
autoEvent->WaitOne( );
Console::WriteLine( "Work method signaled.\nMain ending." );
}
using System;
using System.Threading;
class WaitOne
{
static AutoResetEvent autoEvent = new AutoResetEvent(false);
static void Main()
{
Console.WriteLine("Main starting.");
ThreadPool.QueueUserWorkItem(
new WaitCallback(WorkMethod), autoEvent);
// Wait for work method to signal.
autoEvent.WaitOne();
Console.WriteLine("Work method signaled.\nMain ending.");
}
static void WorkMethod(object stateInfo)
{
Console.WriteLine("Work starting.");
// Simulate time spent working.
Thread.Sleep(new Random().Next(100, 2000));
// Signal that work is finished.
Console.WriteLine("Work ending.");
((AutoResetEvent)stateInfo).Set();
}
}
Imports System.Threading
Public Class WaitOne
Shared autoEvent As New AutoResetEvent(False)
<MTAThread> _
Shared Sub Main()
Console.WriteLine("Main starting.")
ThreadPool.QueueUserWorkItem(AddressOf WorkMethod, autoEvent)
' Wait for work method to signal.
autoEvent.WaitOne()
Console.WriteLine("Work method signaled.")
Console.WriteLine("Main ending.")
End Sub
Shared Sub WorkMethod(stateInfo As Object)
Console.WriteLine("Work starting.")
' Simulate time spent working.
Thread.Sleep(New Random().Next(100, 2000))
' Signal that work is finished.
Console.WriteLine("Work ending.")
CType(stateInfo, AutoResetEvent).Set()
End Sub
End Class
Uwagi
AbandonedMutexExceptionjest nowy w wersji .NET Framework 2.0. W poprzednich wersjach metoda zwraca wartość true
po WaitOne porzuceniu mutexu. Porzucony mutex często wskazuje poważny błąd kodowania. W przypadku mutexu całego systemu może to oznaczać, że aplikacja została nagle zakończona (na przykład przy użyciu Menedżera zadań systemu Windows). Wyjątek zawiera informacje przydatne do debugowania.
Obiekt wywołujący tej metody blokuje bezterminowo, dopóki bieżące wystąpienie nie otrzyma sygnału. Użyj tej metody, aby zablokować, dopóki WaitHandle sygnał z innego wątku nie zostanie wygenerowany, na przykład po zakończeniu operacji asynchronicznej. Aby uzyskać więcej informacji, zobacz IAsyncResult interfejs.
Wywołanie tego przeciążenia metody jest równoważne wywołaniu WaitOne(Int32, Boolean) przeciążenia metody i określeniu -1 lub Timeout.Infinite dla pierwszego parametru i false
drugiego parametru.
Zastąp tę metodę, aby dostosować zachowanie klas pochodnych.
Dotyczy
WaitOne(Int32)
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
Blokuje bieżący wątek do WaitHandle momentu odebrania sygnału przy użyciu 32-bitowej liczby całkowitej podpisanej w celu określenia interwału czasu w milisekundach.
public:
virtual bool WaitOne(int millisecondsTimeout);
public virtual bool WaitOne (int millisecondsTimeout);
abstract member WaitOne : int -> bool
override this.WaitOne : int -> bool
Public Overridable Function WaitOne (millisecondsTimeout As Integer) As Boolean
Parametry
Zwraca
true
jeśli bieżące wystąpienie odbiera sygnał; w przeciwnym razie , false
.
Wyjątki
Bieżące wystąpienie zostało już usunięte.
millisecondsTimeout
jest liczbą ujemną inną niż -1, która reprezentuje nieskończony limit czasu.
Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.
Bieżące wystąpienie jest przezroczystym serwerem proxy dla WaitHandle innej domeny aplikacji.
Przykłady
W poniższym przykładzie kodu pokazano, jak użyć uchwytu oczekiwania, aby zatrzymać proces podczas oczekiwania na zakończenie wykonywania wątku w tle.
using namespace System;
using namespace System::Threading;
ref class WaitOne
{
private:
WaitOne(){}
public:
static void WorkMethod( Object^ stateInfo )
{
Console::WriteLine( "Work starting." );
// Simulate time spent working.
Thread::Sleep( (gcnew Random)->Next( 100, 2000 ) );
// Signal that work is finished.
Console::WriteLine( "Work ending." );
dynamic_cast<AutoResetEvent^>(stateInfo)->Set();
}
};
int main()
{
Console::WriteLine( "Main starting." );
AutoResetEvent^ autoEvent = gcnew AutoResetEvent( false );
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &WaitOne::WorkMethod ), autoEvent );
// Wait for work method to signal.
if ( autoEvent->WaitOne( 1000 ) )
{
Console::WriteLine( "Work method signaled." );
}
else
{
Console::WriteLine( "Timed out waiting for work "
"method to signal." );
}
Console::WriteLine( "Main ending." );
}
using System;
using System.Threading;
class WaitOne
{
static AutoResetEvent autoEvent = new AutoResetEvent(false);
static void Main()
{
Console.WriteLine("Main starting.");
ThreadPool.QueueUserWorkItem(
new WaitCallback(WorkMethod), autoEvent);
// Wait for work method to signal.
if(autoEvent.WaitOne(1000))
{
Console.WriteLine("Work method signaled.");
}
else
{
Console.WriteLine("Timed out waiting for work " +
"method to signal.");
}
Console.WriteLine("Main ending.");
}
static void WorkMethod(object stateInfo)
{
Console.WriteLine("Work starting.");
// Simulate time spent working.
Thread.Sleep(new Random().Next(100, 2000));
// Signal that work is finished.
Console.WriteLine("Work ending.");
((AutoResetEvent)stateInfo).Set();
}
}
Imports System.Threading
Public Class WaitOne
Shared autoEvent As New AutoResetEvent(False)
<MTAThread> _
Shared Sub Main()
Console.WriteLine("Main starting.")
ThreadPool.QueueUserWorkItem(AddressOf WorkMethod, autoEvent)
' Wait for work method to signal.
If autoEvent.WaitOne(1000) Then
Console.WriteLine("Work method signaled.")
Else
Console.WriteLine("Timed out waiting for work " & _
"method to signal.")
End If
Console.WriteLine("Main ending.")
End Sub
Shared Sub WorkMethod(stateInfo As Object)
Console.WriteLine("Work starting.")
' Simulate time spent working.
Thread.Sleep(New Random().Next(100, 2000))
' Signal that work is finished.
Console.WriteLine("Work ending.")
CType(stateInfo, AutoResetEvent).Set()
End Sub
End Class
Uwagi
Jeśli millisecondsTimeout
jest zero, metoda nie blokuje. Testuje stan uchwytu oczekiwania i zwraca natychmiast.
Obiekt wywołujący tej metody blokuje, dopóki bieżące wystąpienie nie otrzyma sygnału lub przekroczenia limitu czasu. Użyj tej metody, aby zablokować, dopóki WaitHandle sygnał z innego wątku nie zostanie wygenerowany, na przykład po zakończeniu operacji asynchronicznej. Aby uzyskać więcej informacji, zobacz IAsyncResult interfejs.
Zastąp tę metodę, aby dostosować zachowanie klas pochodnych.
Wywoływanie tego przeciążenia metody jest takie samo, jak wywoływanie WaitOne(Int32, Boolean) przeciążenia i określanie false
wartości .exitContext
Dotyczy
WaitOne(TimeSpan)
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
Blokuje bieżący wątek, dopóki bieżące wystąpienie nie otrzyma sygnału przy użyciu elementu , TimeSpan aby określić interwał czasu.
public:
virtual bool WaitOne(TimeSpan timeout);
public virtual bool WaitOne (TimeSpan timeout);
abstract member WaitOne : TimeSpan -> bool
override this.WaitOne : TimeSpan -> bool
Public Overridable Function WaitOne (timeout As TimeSpan) As Boolean
Parametry
- timeout
- TimeSpan
Element TimeSpan reprezentujący liczbę milisekund oczekiwania lub wartość reprezentującą TimeSpan -1 milisekundy oczekiwania na czas nieokreślony.
Zwraca
true
jeśli bieżące wystąpienie odbiera sygnał; w przeciwnym razie , false
.
Wyjątki
Bieżące wystąpienie zostało już usunięte.
timeout
jest liczbą ujemną inną niż -1 milisekund, która reprezentuje nieskończony limit czasu.
-lub-
timeout
wartość jest większa niż Int32.MaxValue.
Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.
Bieżące wystąpienie jest przezroczystym serwerem proxy dla WaitHandle innej domeny aplikacji.
Uwagi
Jeśli timeout
jest zero, metoda nie blokuje. Testuje stan uchwytu oczekiwania i zwraca natychmiast.
Obiekt wywołujący tej metody blokuje, dopóki bieżące wystąpienie nie otrzyma sygnału lub przekroczenia limitu czasu. Użyj tej metody, aby zablokować, dopóki WaitHandle sygnał z innego wątku nie zostanie wygenerowany, na przykład po zakończeniu operacji asynchronicznej. Aby uzyskać więcej informacji, zobacz IAsyncResult interfejs.
Zastąp tę metodę, aby dostosować zachowanie klas pochodnych.
Wartość maksymalna to timeout
Int32.MaxValue.
Wywoływanie tego przeciążenia metody jest takie samo, jak wywoływanie WaitOne(TimeSpan, Boolean) przeciążenia i określanie false
wartości .exitContext
Dotyczy
WaitOne(Int32, Boolean)
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
Blokuje bieżący wątek do WaitHandle momentu odebrania sygnału przy użyciu 32-bitowej liczby całkowitej podpisanej w celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.
public:
virtual bool WaitOne(int millisecondsTimeout, bool exitContext);
public virtual bool WaitOne (int millisecondsTimeout, bool exitContext);
abstract member WaitOne : int * bool -> bool
override this.WaitOne : int * bool -> bool
Public Overridable Function WaitOne (millisecondsTimeout As Integer, exitContext As Boolean) As Boolean
Parametry
- exitContext
- Boolean
true
aby zamknąć domenę synchronizacji dla kontekstu przed oczekiwaniem (jeśli w zsynchronizowanym kontekście) i ponownie go później; w przeciwnym razie , false
.
Zwraca
true
jeśli bieżące wystąpienie odbiera sygnał; w przeciwnym razie , false
.
Wyjątki
Bieżące wystąpienie zostało już usunięte.
millisecondsTimeout
jest liczbą ujemną inną niż -1, która reprezentuje nieskończony limit czasu.
Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.
Bieżące wystąpienie jest przezroczystym serwerem proxy dla WaitHandle innej domeny aplikacji.
Przykłady
W poniższym przykładzie pokazano, jak WaitOne(Int32, Boolean) przeciążenie metody działa, gdy jest wywoływane w domenie synchronizacji. Najpierw wątek czeka z ustawioną wartością exitContext
false
i blokuje do momentu wygaśnięcia limitu czasu oczekiwania. Drugi wątek jest wykonywany po zakończeniu pierwszego wątku i oczekiwaniu z ustawionym exitContext
na true
wartość . Wywołanie sygnalizatora oczekiwania dla tego drugiego wątku nie jest zablokowane, a wątek zostanie zakończony przed przekroczeniem limitu czasu oczekiwania.
using namespace System;
using namespace System::Threading;
using namespace System::Runtime::Remoting::Contexts;
[Synchronization(true)]
public ref class SyncingClass : ContextBoundObject
{
private:
EventWaitHandle^ waitHandle;
public:
SyncingClass()
{
waitHandle =
gcnew EventWaitHandle(false, EventResetMode::ManualReset);
}
void Signal()
{
Console::WriteLine("Thread[{0:d4}]: Signalling...", Thread::CurrentThread->GetHashCode());
waitHandle->Set();
}
void DoWait(bool leaveContext)
{
bool signalled;
waitHandle->Reset();
Console::WriteLine("Thread[{0:d4}]: Waiting...", Thread::CurrentThread->GetHashCode());
signalled = waitHandle->WaitOne(3000, leaveContext);
if (signalled)
{
Console::WriteLine("Thread[{0:d4}]: Wait released!!!", Thread::CurrentThread->GetHashCode());
}
else
{
Console::WriteLine("Thread[{0:d4}]: Wait timeout!!!", Thread::CurrentThread->GetHashCode());
}
}
};
public ref class TestSyncDomainWait
{
public:
static void Main()
{
SyncingClass^ syncClass = gcnew SyncingClass();
Thread^ runWaiter;
Console::WriteLine("\nWait and signal INSIDE synchronization domain:\n");
runWaiter = gcnew Thread(gcnew ParameterizedThreadStart(&TestSyncDomainWait::RunWaitKeepContext));
runWaiter->Start(syncClass);
Thread::Sleep(1000);
Console::WriteLine("Thread[{0:d4}]: Signal...", Thread::CurrentThread->GetHashCode());
// This call to Signal will block until the timeout in DoWait expires.
syncClass->Signal();
runWaiter->Join();
Console::WriteLine("\nWait and signal OUTSIDE synchronization domain:\n");
runWaiter = gcnew Thread(gcnew ParameterizedThreadStart(&TestSyncDomainWait::RunWaitLeaveContext));
runWaiter->Start(syncClass);
Thread::Sleep(1000);
Console::WriteLine("Thread[{0:d4}]: Signal...", Thread::CurrentThread->GetHashCode());
// This call to Signal is unblocked and will set the wait handle to
// release the waiting thread.
syncClass->Signal();
runWaiter->Join();
}
static void RunWaitKeepContext(Object^ parm)
{
((SyncingClass^)parm)->DoWait(false);
}
static void RunWaitLeaveContext(Object^ parm)
{
((SyncingClass^)parm)->DoWait(true);
}
};
int main()
{
TestSyncDomainWait::Main();
}
// The output for the example program will be similar to the following:
//
// Wait and signal INSIDE synchronization domain:
//
// Thread[0004]: Waiting...
// Thread[0001]: Signal...
// Thread[0004]: Wait timeout!!!
// Thread[0001]: Signalling...
//
// Wait and signal OUTSIDE synchronization domain:
//
// Thread[0006]: Waiting...
// Thread[0001]: Signal...
// Thread[0001]: Signalling...
// Thread[0006]: Wait released!!!
using System;
using System.Threading;
using System.Runtime.Remoting.Contexts;
[Synchronization(true)]
public class SyncingClass : ContextBoundObject
{
private EventWaitHandle waitHandle;
public SyncingClass()
{
waitHandle =
new EventWaitHandle(false, EventResetMode.ManualReset);
}
public void Signal()
{
Console.WriteLine("Thread[{0:d4}]: Signalling...", Thread.CurrentThread.GetHashCode());
waitHandle.Set();
}
public void DoWait(bool leaveContext)
{
bool signalled;
waitHandle.Reset();
Console.WriteLine("Thread[{0:d4}]: Waiting...", Thread.CurrentThread.GetHashCode());
signalled = waitHandle.WaitOne(3000, leaveContext);
if (signalled)
{
Console.WriteLine("Thread[{0:d4}]: Wait released!!!", Thread.CurrentThread.GetHashCode());
}
else
{
Console.WriteLine("Thread[{0:d4}]: Wait timeout!!!", Thread.CurrentThread.GetHashCode());
}
}
}
public class TestSyncDomainWait
{
public static void Main()
{
SyncingClass syncClass = new SyncingClass();
Thread runWaiter;
Console.WriteLine("\nWait and signal INSIDE synchronization domain:\n");
runWaiter = new Thread(RunWaitKeepContext);
runWaiter.Start(syncClass);
Thread.Sleep(1000);
Console.WriteLine("Thread[{0:d4}]: Signal...", Thread.CurrentThread.GetHashCode());
// This call to Signal will block until the timeout in DoWait expires.
syncClass.Signal();
runWaiter.Join();
Console.WriteLine("\nWait and signal OUTSIDE synchronization domain:\n");
runWaiter = new Thread(RunWaitLeaveContext);
runWaiter.Start(syncClass);
Thread.Sleep(1000);
Console.WriteLine("Thread[{0:d4}]: Signal...", Thread.CurrentThread.GetHashCode());
// This call to Signal is unblocked and will set the wait handle to
// release the waiting thread.
syncClass.Signal();
runWaiter.Join();
}
public static void RunWaitKeepContext(object parm)
{
((SyncingClass)parm).DoWait(false);
}
public static void RunWaitLeaveContext(object parm)
{
((SyncingClass)parm).DoWait(true);
}
}
// The output for the example program will be similar to the following:
//
// Wait and signal INSIDE synchronization domain:
//
// Thread[0004]: Waiting...
// Thread[0001]: Signal...
// Thread[0004]: Wait timeout!!!
// Thread[0001]: Signalling...
//
// Wait and signal OUTSIDE synchronization domain:
//
// Thread[0006]: Waiting...
// Thread[0001]: Signal...
// Thread[0001]: Signalling...
// Thread[0006]: Wait released!!!
Imports System.Threading
Imports System.Runtime.Remoting.Contexts
<Synchronization(true)>
Public Class SyncingClass
Inherits ContextBoundObject
Private waitHandle As EventWaitHandle
Public Sub New()
waitHandle = New EventWaitHandle(false, EventResetMode.ManualReset)
End Sub
Public Sub Signal()
Console.WriteLine("Thread[{0:d4}]: Signalling...", Thread.CurrentThread.GetHashCode())
waitHandle.Set()
End Sub
Public Sub DoWait(leaveContext As Boolean)
Dim signalled As Boolean
waitHandle.Reset()
Console.WriteLine("Thread[{0:d4}]: Waiting...", Thread.CurrentThread.GetHashCode())
signalled = waitHandle.WaitOne(3000, leaveContext)
If signalled Then
Console.WriteLine("Thread[{0:d4}]: Wait released!!!", Thread.CurrentThread.GetHashCode())
Else
Console.WriteLine("Thread[{0:d4}]: Wait timeout!!!", Thread.CurrentThread.GetHashCode())
End If
End Sub
End Class
Public Class TestSyncDomainWait
Public Shared Sub Main()
Dim syncClass As New SyncingClass()
Dim runWaiter As Thread
Console.WriteLine(Environment.NewLine + "Wait and signal INSIDE synchronization domain:" + Environment.NewLine)
runWaiter = New Thread(AddressOf RunWaitKeepContext)
runWaiter.Start(syncClass)
Thread.Sleep(1000)
Console.WriteLine("Thread[{0:d4}]: Signal...", Thread.CurrentThread.GetHashCode())
' This call to Signal will block until the timeout in DoWait expires.
syncClass.Signal()
runWaiter.Join()
Console.WriteLine(Environment.NewLine + "Wait and signal OUTSIDE synchronization domain:" + Environment.NewLine)
runWaiter = New Thread(AddressOf RunWaitLeaveContext)
runWaiter.Start(syncClass)
Thread.Sleep(1000)
Console.WriteLine("Thread[{0:d4}]: Signal...", Thread.CurrentThread.GetHashCode())
' This call to Signal is unblocked and will set the wait handle to
' release the waiting thread.
syncClass.Signal()
runWaiter.Join()
End Sub
Public Shared Sub RunWaitKeepContext(parm As Object)
Dim syncClass As SyncingClass = CType(parm, SyncingClass)
syncClass.DoWait(False)
End Sub
Public Shared Sub RunWaitLeaveContext(parm As Object)
Dim syncClass As SyncingClass = CType(parm, SyncingClass)
syncClass.DoWait(True)
End Sub
End Class
' The output for the example program will be similar to the following:
'
' Wait and signal INSIDE synchronization domain:
'
' Thread[0004]: Waiting...
' Thread[0001]: Signal...
' Thread[0004]: Wait timeout!!!
' Thread[0001]: Signalling...
'
' Wait and signal OUTSIDE synchronization domain:
'
' Thread[0006]: Waiting...
' Thread[0001]: Signal...
' Thread[0001]: Signalling...
' Thread[0006]: Wait released!!!
Uwagi
Jeśli millisecondsTimeout
jest zero, metoda nie blokuje. Testuje stan uchwytu oczekiwania i zwraca natychmiast.
Jeśli mutex zostanie porzucony, AbandonedMutexException zostanie zgłoszony. Porzucony mutex często wskazuje poważny błąd kodowania. W przypadku mutexu całego systemu może to oznaczać, że aplikacja została nagle zakończona (na przykład przy użyciu Menedżera zadań systemu Windows). Wyjątek zawiera informacje przydatne do debugowania.
Obiekt wywołujący tej metody blokuje, dopóki bieżące wystąpienie nie otrzyma sygnału lub przekroczenia limitu czasu. Użyj tej metody, aby zablokować, dopóki WaitHandle sygnał z innego wątku nie zostanie wygenerowany, na przykład po zakończeniu operacji asynchronicznej. Aby uzyskać więcej informacji, zobacz IAsyncResult interfejs.
Zastąp tę metodę, aby dostosować zachowanie klas pochodnych.
Zamykanie kontekstu
Parametr exitContext
nie ma wpływu, chyba że ta metoda jest wywoływana z wewnątrz kontekstu zarządzanego niezdefault. Kontekst zarządzany może być niezdefault, jeśli wątek znajduje się wewnątrz wywołania wystąpienia klasy pochodzącej z ContextBoundObjectklasy . Nawet jeśli obecnie wykonujesz metodę w klasie, która nie pochodzi z ContextBoundObjectklasy , na przykład String, możesz być w kontekście niezdefault, jeśli element ContextBoundObject znajduje się na stosie w bieżącej domenie aplikacji.
Gdy kod jest wykonywany w kontekście niezdefinicyjnym, określając true
przyczynę exitContext
zakończenia kontekstu zarządzanego niezdefault (czyli przejścia do kontekstu domyślnego) przed wykonaniem tej metody. Wątek powraca do oryginalnego kontekstu niezdefault po zakończeniu wywołania tej metody.
Zamknięcie kontekstu może być przydatne, gdy klasa powiązana z kontekstem SynchronizationAttribute ma atrybut . W takim przypadku wszystkie wywołania do składowych klasy są automatycznie synchronizowane, a domena synchronizacji to cała treść kodu dla klasy. Jeśli kod w stosie wywołań elementu członkowskiego wywołuje tę metodę i określa true
dla exitContext
elementu , wątek zamyka domenę synchronizacji, co umożliwia wątkowi zablokowanemu wywołanie do dowolnego elementu członkowskiego obiektu. Gdy ta metoda zostanie zwrócona, wątek, który wykonał wywołanie, musi poczekać na ponowne włączenie domeny synchronizacji.
Dotyczy
WaitOne(TimeSpan, Boolean)
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
- Źródło:
- WaitHandle.cs
Blokuje bieżący wątek do momentu odebrania sygnału przez bieżące wystąpienie przy użyciu parametru w TimeSpan celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.
public:
virtual bool WaitOne(TimeSpan timeout, bool exitContext);
public virtual bool WaitOne (TimeSpan timeout, bool exitContext);
abstract member WaitOne : TimeSpan * bool -> bool
override this.WaitOne : TimeSpan * bool -> bool
Public Overridable Function WaitOne (timeout As TimeSpan, exitContext As Boolean) As Boolean
Parametry
- timeout
- TimeSpan
Wartość TimeSpan reprezentująca liczbę milisekund oczekiwania lub wartość reprezentująca TimeSpan -1 milisekundy oczekiwania na czas nieokreślony.
- exitContext
- Boolean
true
aby zamknąć domenę synchronizacji dla kontekstu przed oczekiwaniem (jeśli w zsynchronizowanym kontekście) i ponownie go później; w przeciwnym razie , false
.
Zwraca
true
jeśli bieżące wystąpienie odbiera sygnał; w przeciwnym razie , false
.
Wyjątki
Bieżące wystąpienie zostało już usunięte.
timeout
jest liczbą ujemną inną niż -1 milisekund, która reprezentuje nieskończony limit czasu.
-lub-
timeout
wartość jest większa niż Int32.MaxValue.
Oczekiwanie zostało ukończone, ponieważ wątek zakończył się bez zwolnienia mutexu.
Bieżące wystąpienie jest przezroczystym serwerem proxy dla domeny WaitHandle w innej domenie aplikacji.
Przykłady
W poniższym przykładzie kodu pokazano, jak użyć uchwytu oczekiwania, aby zatrzymać proces podczas oczekiwania na zakończenie wykonywania wątku w tle.
using namespace System;
using namespace System::Threading;
ref class WaitOne
{
private:
WaitOne(){}
public:
static void WorkMethod( Object^ stateInfo )
{
Console::WriteLine( "Work starting." );
// Simulate time spent working.
Thread::Sleep( (gcnew Random)->Next( 100, 2000 ) );
// Signal that work is finished.
Console::WriteLine( "Work ending." );
dynamic_cast<AutoResetEvent^>(stateInfo)->Set();
}
};
int main()
{
Console::WriteLine( "Main starting." );
AutoResetEvent^ autoEvent = gcnew AutoResetEvent( false );
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &WaitOne::WorkMethod ), autoEvent );
// Wait for work method to signal.
if ( autoEvent->WaitOne( TimeSpan(0,0,1), false ) )
{
Console::WriteLine( "Work method signaled." );
}
else
{
Console::WriteLine( "Timed out waiting for work "
"method to signal." );
}
Console::WriteLine( "Main ending." );
}
using System;
using System.Threading;
class WaitOne
{
static AutoResetEvent autoEvent = new AutoResetEvent(false);
static void Main()
{
Console.WriteLine("Main starting.");
ThreadPool.QueueUserWorkItem(
new WaitCallback(WorkMethod), autoEvent);
// Wait for work method to signal.
if(autoEvent.WaitOne(new TimeSpan(0, 0, 1), false))
{
Console.WriteLine("Work method signaled.");
}
else
{
Console.WriteLine("Timed out waiting for work " +
"method to signal.");
}
Console.WriteLine("Main ending.");
}
static void WorkMethod(object stateInfo)
{
Console.WriteLine("Work starting.");
// Simulate time spent working.
Thread.Sleep(new Random().Next(100, 2000));
// Signal that work is finished.
Console.WriteLine("Work ending.");
((AutoResetEvent)stateInfo).Set();
}
}
Imports System.Threading
Public Class WaitOne
Shared autoEvent As New AutoResetEvent(False)
<MTAThread> _
Shared Sub Main()
Console.WriteLine("Main starting.")
ThreadPool.QueueUserWorkItem(AddressOf WorkMethod, autoEvent)
' Wait for work method to signal.
If autoEvent.WaitOne(New TimeSpan(0, 0, 1), False) Then
Console.WriteLine("Work method signaled.")
Else
Console.WriteLine("Timed out waiting for work " & _
"method to signal.")
End If
Console.WriteLine("Main ending.")
End Sub
Shared Sub WorkMethod(stateInfo As Object)
Console.WriteLine("Work starting.")
' Simulate time spent working.
Thread.Sleep(New Random().Next(100, 2000))
' Signal that work is finished.
Console.WriteLine("Work ending.")
CType(stateInfo, AutoResetEvent).Set()
End Sub
End Class
Uwagi
Jeśli timeout
wartość jest równa zero, metoda nie blokuje. Testuje stan dojścia oczekiwania i zwraca natychmiast.
Jeśli mutex zostanie porzucony, AbandonedMutexException jest zgłaszany. Porzucony mutex często wskazuje poważny błąd kodowania. W przypadku całego systemu mutex może wskazywać, że aplikacja została nagle zakończona (na przykład za pomocą Menedżera zadań systemu Windows). Wyjątek zawiera informacje przydatne do debugowania.
Obiekt wywołujący tej metody blokuje, dopóki bieżące wystąpienie nie odbierze sygnału lub upłynął limit czasu. Ta metoda służy do blokowania do momentu WaitHandle odebrania sygnału z innego wątku, takiego jak jest generowany po zakończeniu operacji asynchronicznej. Aby uzyskać więcej informacji, zobacz IAsyncResult interfejs.
Zastąp tę metodę, aby dostosować zachowanie klas pochodnych.
Wartość maksymalna dla parametru timeout
to Int32.MaxValue.
Zamykanie kontekstu
Parametr exitContext
nie ma wpływu, chyba że ta metoda jest wywoływana z wewnątrz kontekstu zarządzanego bez definicji. Kontekst zarządzany może być niezdefault, jeśli wątek znajduje się wewnątrz wywołania do wystąpienia klasy pochodzącej z ContextBoundObjectklasy . Nawet jeśli obecnie wykonujesz metodę w klasie, która nie pochodzi z ContextBoundObjectklasy , na przykład String, możesz znajdować się w kontekście niedefault, jeśli element ContextBoundObject znajduje się na stosie w bieżącej domenie aplikacji.
Gdy kod jest wykonywany w kontekście niedefault, określając true
, że exitContext
wątek ma zamknąć niedefaultowy kontekst zarządzany (tj. przejść do kontekstu domyślnego) przed wykonaniem tej metody. Po zakończeniu wywołania tej metody wątek powraca do oryginalnego kontekstu niezdefaultowego.
Zamknięcie kontekstu może być przydatne, gdy klasa powiązana kontekstem SynchronizationAttribute ma atrybut . W takim przypadku wszystkie wywołania elementów członkowskich klasy są automatycznie synchronizowane, a domena synchronizacji jest całą treścią kodu dla klasy. Jeśli kod w stosie wywołań elementu członkowskiego wywołuje tę metodę i określa true
metodę exitContext
, wątek kończy domenę synchronizacji, co umożliwia kontynuowanie wątku, który jest blokowany w wywołaniu dowolnego elementu członkowskiego obiektu. Gdy ta metoda powróci, wątek, który wykonał wywołanie, musi poczekać na ponowne włączenie domeny synchronizacji.