WaitHandle.WaitOne Метод
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Блокирует текущий поток до получения сигнала объектом WaitHandle.
Перегрузки
WaitOne() |
Блокирует текущий поток до получения сигнала объектом WaitHandle. |
WaitOne(Int32) |
Блокирует текущий поток до получения текущим дескриптором WaitHandle сигнала, используя 32-разрядное целое число со знаком для указания интервала времени в миллисекундах. |
WaitOne(TimeSpan) |
Блокирует текущий поток до получения сигнала текущим экземпляром, используя значение типа TimeSpan для указания интервала времени. |
WaitOne(Int32, Boolean) |
Блокирует текущий поток до получения сигнала текущим объектом WaitHandle, используя 32-разрядное целое число со знаком для задания периода времени и указывая, следует ли выйти из домена синхронизации до начала ожидания. |
WaitOne(TimeSpan, Boolean) |
Блокирует текущий поток до получения сигнала текущим экземпляром, используя значение типа TimeSpan для задания интервала времени и указывая, следует ли выйти из домена синхронизации до начала ожидания. |
WaitOne()
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
Блокирует текущий поток до получения сигнала объектом WaitHandle.
public:
virtual bool WaitOne();
public virtual bool WaitOne ();
abstract member WaitOne : unit -> bool
override this.WaitOne : unit -> bool
Public Overridable Function WaitOne () As Boolean
Возвращаемое значение
Значение true
, если текущий экземпляр получает сигнал. Пока текущий экземпляр не сигнализирует, метод WaitOne() не возвращает управление.
Исключения
Текущий экземпляр уже удален.
Ожидание закончилось, так как поток завершил работу, не освободив мьютекс.
Текущий экземпляр является прозрачным прокси для объекта WaitHandle в другом домене приложения.
Примеры
В следующем примере кода показано, как использовать дескриптор ожидания, чтобы не допустить завершения процесса, пока он ожидает завершения выполнения фонового потока.
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
Комментарии
AbandonedMutexExceptionявляется новым в платформа .NET Framework версии 2.0. В предыдущих версиях метод возвращает значение true
при WaitOne отказе от мьютекса. Отказ от мьютекса часто указывает на серьезную ошибку кодирования. В случае мьютекса всей системы это может указывать на то, что приложение было внезапно завершено (например, с помощью диспетчера задач Windows). Исключение содержит сведения, полезные для отладки.
Вызывающий объект этого метода блокируется на неопределенный срок, пока текущий экземпляр не получит сигнал. Используйте этот метод для блокировки до тех пор, пока WaitHandle не получит сигнал из другого потока, например при завершении асинхронной операции. Дополнительные сведения см. в описании интерфейса IAsyncResult.
Вызов перегрузки этого метода эквивалентен вызову перегрузки WaitOne(Int32, Boolean) метода и указанию -1 или Timeout.Infinite для первого параметра и false
для второго параметра.
Переопределите этот метод, чтобы настроить поведение производных классов.
Применяется к
WaitOne(Int32)
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
Блокирует текущий поток до получения текущим дескриптором WaitHandle сигнала, используя 32-разрядное целое число со знаком для указания интервала времени в миллисекундах.
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
Параметры
- millisecondsTimeout
- Int32
Время ожидания в миллисекундах или функция Infinite (-1) в случае неограниченного времени ожидания.
Возвращаемое значение
Значение true
при получении сигнала текущим экземпляром; в противном случае — значение false
.
Исключения
Текущий экземпляр уже удален.
Параметр millisecondsTimeout
является отрицательным числом, отличным от –1, что означает бесконечное время ожидания.
Ожидание закончилось, так как поток завершил работу, не освободив мьютекс.
Текущий экземпляр является прозрачным прокси для объекта WaitHandle в другом домене приложения.
Примеры
В следующем примере кода показано, как использовать дескриптор ожидания, чтобы не допустить завершения процесса, пока он ожидает завершения выполнения фонового потока.
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
Комментарии
Если millisecondsTimeout
равно нулю, метод не блокирует. Он проверяет состояние дескриптора ожидания и возвращает немедленно.
Вызывающий объект этого метода блокируется до тех пор, пока текущий экземпляр не получит сигнал или не наступает время ожидания. Используйте этот метод для блокировки до тех пор, пока WaitHandle не получит сигнал из другого потока, например при завершении асинхронной операции. Дополнительные сведения см. в описании интерфейса IAsyncResult.
Переопределите этот метод, чтобы настроить поведение производных классов.
Вызов перегрузки этого метода совпадает с вызовом перегрузки WaitOne(Int32, Boolean) и указанием false
для exitContext
.
Применяется к
WaitOne(TimeSpan)
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
Блокирует текущий поток до получения сигнала текущим экземпляром, используя значение типа TimeSpan для указания интервала времени.
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
Параметры
- timeout
- TimeSpan
Период TimeSpan, представляющий время ожидания в миллисекундах, или период TimeSpan, представляющий -1 миллисекунду для неограниченного ожидания.
Возвращаемое значение
Значение true
при получении сигнала текущим экземпляром; в противном случае — значение false
.
Исключения
Текущий экземпляр уже удален.
timeout
является отрицательным числом, отличным от -1 миллисекунды, которое представляет неограниченное время ожидания.
-или-
timeout
больше , чем Int32.MaxValue.
Ожидание закончилось, так как поток завершил работу, не освободив мьютекс.
Текущий экземпляр является прозрачным прокси для объекта WaitHandle в другом домене приложения.
Комментарии
Если timeout
равно нулю, метод не блокирует. Он проверяет состояние дескриптора ожидания и возвращает немедленно.
Вызывающий объект этого метода блокируется до тех пор, пока текущий экземпляр не получит сигнал или не наступает время ожидания. Используйте этот метод для блокировки до тех пор, пока WaitHandle не получит сигнал из другого потока, например при завершении асинхронной операции. Дополнительные сведения см. в описании интерфейса IAsyncResult.
Переопределите этот метод, чтобы настроить поведение производных классов.
Максимальное значение для timeout
— Int32.MaxValue.
Вызов перегрузки этого метода совпадает с вызовом перегрузки WaitOne(TimeSpan, Boolean) и указанием false
для exitContext
.
Применяется к
WaitOne(Int32, Boolean)
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
Блокирует текущий поток до получения сигнала текущим объектом WaitHandle, используя 32-разрядное целое число со знаком для задания периода времени и указывая, следует ли выйти из домена синхронизации до начала ожидания.
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
Параметры
- millisecondsTimeout
- Int32
Время ожидания в миллисекундах или функция Infinite (-1) в случае неограниченного времени ожидания.
- exitContext
- Boolean
Значение true
для выхода из домена синхронизации в текущем контексте перед ожиданием (в синхронизированном контексте) с его последующим повторным получением; в противном случае — false
.
Возвращаемое значение
Значение true
при получении сигнала текущим экземпляром; в противном случае — значение false
.
Исключения
Текущий экземпляр уже удален.
Параметр millisecondsTimeout
является отрицательным числом, отличным от –1, что означает бесконечное время ожидания.
Ожидание закончилось, так как поток завершил работу, не освободив мьютекс.
Текущий экземпляр является прозрачным прокси для объекта WaitHandle в другом домене приложения.
Примеры
В следующем примере показано поведение перегрузки WaitOne(Int32, Boolean) метода при вызове в домене синхронизации. Во-первых, поток ожидает с exitContext
заданным значением false
и блокирует время ожидания, пока не истечет время ожидания. Второй поток выполняется после завершения первого потока и ожидает с exitContext
параметром true
. Вызов сигнала дескриптора ожидания для этого второго потока не блокируется, и поток завершается до истечения времени ожидания.
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!!!
Комментарии
Если millisecondsTimeout
равно нулю, метод не блокирует. Он проверяет состояние дескриптора ожидания и возвращает немедленно.
При отказе от мьютекса AbandonedMutexException создается исключение . Отказ от мьютекса часто указывает на серьезную ошибку кодирования. В случае мьютекса всей системы это может указывать на то, что приложение было внезапно завершено (например, с помощью диспетчера задач Windows). Исключение содержит сведения, полезные для отладки.
Вызывающий объект этого метода блокируется до тех пор, пока текущий экземпляр не получит сигнал или не наступает время ожидания. Используйте этот метод для блокировки до тех пор, пока WaitHandle не получит сигнал из другого потока, например при завершении асинхронной операции. Дополнительные сведения см. в описании интерфейса IAsyncResult.
Переопределите этот метод, чтобы настроить поведение производных классов.
Выход из контекста
Параметр exitContext
не действует, если этот метод не вызывается из неразрешимого управляемого контекста. Управляемый контекст может быть неразрешен, если поток находится в вызове экземпляра класса, производного от ContextBoundObject. Даже если в данный момент вы выполняете метод в классе, который не является производным от , например String, вы можете находиться в контексте, отличном от ContextBoundObjectтекущего домена приложения, если ContextBoundObject объект находится в стеке в текущем домене приложения.
Если код выполняется в контексте, отличном от параметров, указание true
параметра приводит exitContext
к выходу потока из неотделенного управляемого контекста (т. е. для перехода в контекст по умолчанию) перед выполнением этого метода. После завершения вызова этого метода поток возвращается в исходный контекст, отличный от текущего.
Выход из контекста может быть полезен, если у класса, связанного с контекстом SynchronizationAttribute , есть атрибут . В этом случае все вызовы членов класса синхронизируются автоматически, а доменом синхронизации является весь текст кода для класса. Если код в стеке вызовов true
элемента вызывает этот метод и указывает для exitContext
, поток выходит из домена синхронизации, что позволяет потоку, заблокированном при вызове любого члена объекта, продолжить работу. При возврате этим методом поток, который сделал вызов, должен дождаться повторного ввести домен синхронизации.
Применяется к
WaitOne(TimeSpan, Boolean)
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
Блокирует текущий поток до получения сигнала текущим экземпляром, используя значение типа TimeSpan для задания интервала времени и указывая, следует ли выйти из домена синхронизации до начала ожидания.
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
Параметры
- timeout
- TimeSpan
Период TimeSpan, представляющий время ожидания в миллисекундах, или период TimeSpan, представляющий -1 миллисекунду для неограниченного ожидания.
- exitContext
- Boolean
Значение true
для выхода из домена синхронизации в текущем контексте перед ожиданием (в синхронизированном контексте) с его последующим повторным получением; в противном случае — false
.
Возвращаемое значение
Значение true
при получении сигнала текущим экземпляром; в противном случае — значение false
.
Исключения
Текущий экземпляр уже удален.
timeout
является отрицательным числом, отличным от -1 миллисекунды, которое представляет неограниченное время ожидания.
-или-
timeout
больше , чем Int32.MaxValue.
Ожидание закончилось, так как поток завершил работу, не освободив мьютекс.
Текущий экземпляр является прозрачным прокси для объекта WaitHandle в другом домене приложения.
Примеры
В следующем примере кода показано, как использовать дескриптор ожидания, чтобы не допустить завершения процесса, пока он ожидает завершения выполнения фонового потока.
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
Комментарии
Если timeout
равно нулю, метод не блокируется. Он проверяет состояние дескриптора ожидания и немедленно возвращается.
При отказе от мьютекса AbandonedMutexException создается исключение . Отказ от мьютекса часто указывает на серьезную ошибку кодирования. В случае системного мьютекса это может означать, что приложение было внезапно завершено (например, с помощью диспетчера задач Windows). Исключение содержит сведения, полезные для отладки.
Вызывающий объект этого метода блокируется до тех пор, пока текущий экземпляр не получит сигнал или не наступает время ожидания. Используйте этот метод для блокировки до тех пор, пока не WaitHandle получит сигнал из другого потока, например при завершении асинхронной операции. Дополнительные сведения см. в описании интерфейса IAsyncResult.
Переопределите этот метод, чтобы настроить поведение производных классов.
Максимальное значение для timeout
— Int32.MaxValue.
Выход из контекста
Параметр exitContext
не действует, если этот метод не вызывается из нестандартного управляемого контекста. Управляемый контекст может быть неразрешен, если поток находится внутри вызова экземпляра класса, производного от ContextBoundObject. Даже если вы в настоящее время выполняете метод в классе, который не является производным от ContextBoundObject, например String, вы можете находиться в контексте, не являющемся стандартным, если ContextBoundObject находится в стеке в текущем домене приложения.
При выполнении кода в контексте, не являющегося стандартным, указание true
для exitContext
приводит к тому, что перед выполнением этого метода поток выйдет из нестандартного управляемого контекста (т. е. для перехода в контекст по умолчанию). Поток возвращается в исходный контекст nondefault после завершения вызова этого метода.
Выход из контекста может быть полезен, если связанный с контекстом класс имеет SynchronizationAttribute атрибут . В этом случае все вызовы членов класса синхронизируются автоматически, а домен синхронизации — это весь текст кода для класса. Если код в стеке вызовов true
члена вызывает этот метод и указывает для exitContext
, поток выходит из домена синхронизации, что позволяет потоку, заблокированном при вызове любого члена объекта, продолжить работу. При возврате этого метода поток, который сделал вызов, должен дождаться повторного ввести домен синхронизации.