ManualResetEvent 类
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
表示必须手动重置信号的线程同步事件。 无法继承此类。
public ref class ManualResetEvent sealed : System::Threading::EventWaitHandle
public ref class ManualResetEvent sealed : System::Threading::WaitHandle
public sealed class ManualResetEvent : System.Threading.EventWaitHandle
public sealed class ManualResetEvent : System.Threading.WaitHandle
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class ManualResetEvent : System.Threading.EventWaitHandle
type ManualResetEvent = class
inherit EventWaitHandle
type ManualResetEvent = class
inherit WaitHandle
[<System.Runtime.InteropServices.ComVisible(true)>]
type ManualResetEvent = class
inherit EventWaitHandle
Public NotInheritable Class ManualResetEvent
Inherits EventWaitHandle
Public NotInheritable Class ManualResetEvent
Inherits WaitHandle
- 继承
- 继承
- 继承
- 属性
示例
以下示例演示如何 ManualResetEvent 工作。 该示例以处于无对齐状态的 ManualResetEvent(即 false
传递给构造函数)开头。 该示例创建三个线程,每个线程通过调用 WaitOne 方法在 ManualResetEvent 上阻止。 当用户按下 Enter 键时,该示例将调用 Set 方法,该方法释放所有三个线程。 与此形成鲜明对比的是 AutoResetEvent 类的行为,该类一次释放一个线程,在每个发布后自动重置。
再次按 Enter 键表明,ManualResetEvent 保持信号状态,直到调用其 Reset 方法:本示例再启动两个线程。 这些线程在调用 WaitOne 方法时不会阻止,而是运行到完成。
再次按 Enter 键会导致示例调用 Reset 方法并启动一个线程,这会在调用 WaitOne时阻止它。 按 Enter 键一次调用 Set 释放最后一个线程,程序结束。
using namespace System;
using namespace System::Threading;
ref class Example
{
private:
// mre is used to block and release threads manually. It is
// created in the unsignaled state.
static ManualResetEvent^ mre = gcnew ManualResetEvent(false);
static void ThreadProc()
{
String^ name = Thread::CurrentThread->Name;
Console::WriteLine(name + " starts and calls mre->WaitOne()");
mre->WaitOne();
Console::WriteLine(name + " ends.");
}
public:
static void Demo()
{
Console::WriteLine("\nStart 3 named threads that block on a ManualResetEvent:\n");
for(int i = 0; i <=2 ; i++)
{
Thread^ t = gcnew Thread(gcnew ThreadStart(ThreadProc));
t->Name = "Thread_" + i;
t->Start();
}
Thread::Sleep(500);
Console::WriteLine("\nWhen all three threads have started, press Enter to call Set()" +
"\nto release all the threads.\n");
Console::ReadLine();
mre->Set();
Thread::Sleep(500);
Console::WriteLine("\nWhen a ManualResetEvent is signaled, threads that call WaitOne()" +
"\ndo not block. Press Enter to show this.\n");
Console::ReadLine();
for(int i = 3; i <= 4; i++)
{
Thread^ t = gcnew Thread(gcnew ThreadStart(ThreadProc));
t->Name = "Thread_" + i;
t->Start();
}
Thread::Sleep(500);
Console::WriteLine("\nPress Enter to call Reset(), so that threads once again block" +
"\nwhen they call WaitOne().\n");
Console::ReadLine();
mre->Reset();
// Start a thread that waits on the ManualResetEvent.
Thread^ t5 = gcnew Thread(gcnew ThreadStart(ThreadProc));
t5->Name = "Thread_5";
t5->Start();
Thread::Sleep(500);
Console::WriteLine("\nPress Enter to call Set() and conclude the demo.");
Console::ReadLine();
mre->Set();
// If you run this example in Visual Studio, uncomment the following line:
//Console::ReadLine();
}
};
int main()
{
Example::Demo();
}
/* This example produces output similar to the following:
Start 3 named threads that block on a ManualResetEvent:
Thread_0 starts and calls mre->WaitOne()
Thread_1 starts and calls mre->WaitOne()
Thread_2 starts and calls mre->WaitOne()
When all three threads have started, press Enter to call Set()
to release all the threads.
Thread_2 ends.
Thread_1 ends.
Thread_0 ends.
When a ManualResetEvent is signaled, threads that call WaitOne()
do not block. Press Enter to show this.
Thread_3 starts and calls mre->WaitOne()
Thread_3 ends.
Thread_4 starts and calls mre->WaitOne()
Thread_4 ends.
Press Enter to call Reset(), so that threads once again block
when they call WaitOne().
Thread_5 starts and calls mre->WaitOne()
Press Enter to call Set() and conclude the demo.
Thread_5 ends.
*/
using System;
using System.Threading;
public class Example
{
// mre is used to block and release threads manually. It is
// created in the unsignaled state.
private static ManualResetEvent mre = new ManualResetEvent(false);
static void Main()
{
Console.WriteLine("\nStart 3 named threads that block on a ManualResetEvent:\n");
for(int i = 0; i <= 2; i++)
{
Thread t = new Thread(ThreadProc);
t.Name = "Thread_" + i;
t.Start();
}
Thread.Sleep(500);
Console.WriteLine("\nWhen all three threads have started, press Enter to call Set()" +
"\nto release all the threads.\n");
Console.ReadLine();
mre.Set();
Thread.Sleep(500);
Console.WriteLine("\nWhen a ManualResetEvent is signaled, threads that call WaitOne()" +
"\ndo not block. Press Enter to show this.\n");
Console.ReadLine();
for(int i = 3; i <= 4; i++)
{
Thread t = new Thread(ThreadProc);
t.Name = "Thread_" + i;
t.Start();
}
Thread.Sleep(500);
Console.WriteLine("\nPress Enter to call Reset(), so that threads once again block" +
"\nwhen they call WaitOne().\n");
Console.ReadLine();
mre.Reset();
// Start a thread that waits on the ManualResetEvent.
Thread t5 = new Thread(ThreadProc);
t5.Name = "Thread_5";
t5.Start();
Thread.Sleep(500);
Console.WriteLine("\nPress Enter to call Set() and conclude the demo.");
Console.ReadLine();
mre.Set();
// If you run this example in Visual Studio, uncomment the following line:
//Console.ReadLine();
}
private static void ThreadProc()
{
string name = Thread.CurrentThread.Name;
Console.WriteLine(name + " starts and calls mre.WaitOne()");
mre.WaitOne();
Console.WriteLine(name + " ends.");
}
}
/* This example produces output similar to the following:
Start 3 named threads that block on a ManualResetEvent:
Thread_0 starts and calls mre.WaitOne()
Thread_1 starts and calls mre.WaitOne()
Thread_2 starts and calls mre.WaitOne()
When all three threads have started, press Enter to call Set()
to release all the threads.
Thread_2 ends.
Thread_0 ends.
Thread_1 ends.
When a ManualResetEvent is signaled, threads that call WaitOne()
do not block. Press Enter to show this.
Thread_3 starts and calls mre.WaitOne()
Thread_3 ends.
Thread_4 starts and calls mre.WaitOne()
Thread_4 ends.
Press Enter to call Reset(), so that threads once again block
when they call WaitOne().
Thread_5 starts and calls mre.WaitOne()
Press Enter to call Set() and conclude the demo.
Thread_5 ends.
*/
Imports System.Threading
Public Class Example
' mre is used to block and release threads manually. It is
' created in the unsignaled state.
Private Shared mre As New ManualResetEvent(False)
<MTAThreadAttribute> _
Shared Sub Main()
Console.WriteLine(vbLf & _
"Start 3 named threads that block on a ManualResetEvent:" & vbLf)
For i As Integer = 0 To 2
Dim t As New Thread(AddressOf ThreadProc)
t.Name = "Thread_" & i
t.Start()
Next i
Thread.Sleep(500)
Console.WriteLine(vbLf & _
"When all three threads have started, press Enter to call Set()" & vbLf & _
"to release all the threads." & vbLf)
Console.ReadLine()
mre.Set()
Thread.Sleep(500)
Console.WriteLine(vbLf & _
"When a ManualResetEvent is signaled, threads that call WaitOne()" & vbLf & _
"do not block. Press Enter to show this." & vbLf)
Console.ReadLine()
For i As Integer = 3 To 4
Dim t As New Thread(AddressOf ThreadProc)
t.Name = "Thread_" & i
t.Start()
Next i
Thread.Sleep(500)
Console.WriteLine(vbLf & _
"Press Enter to call Reset(), so that threads once again block" & vbLf & _
"when they call WaitOne()." & vbLf)
Console.ReadLine()
mre.Reset()
' Start a thread that waits on the ManualResetEvent.
Dim t5 As New Thread(AddressOf ThreadProc)
t5.Name = "Thread_5"
t5.Start()
Thread.Sleep(500)
Console.WriteLine(vbLf & "Press Enter to call Set() and conclude the demo.")
Console.ReadLine()
mre.Set()
' If you run this example in Visual Studio, uncomment the following line:
'Console.ReadLine()
End Sub
Private Shared Sub ThreadProc()
Dim name As String = Thread.CurrentThread.Name
Console.WriteLine(name & " starts and calls mre.WaitOne()")
mre.WaitOne()
Console.WriteLine(name & " ends.")
End Sub
End Class
' This example produces output similar to the following:
'
'Start 3 named threads that block on a ManualResetEvent:
'
'Thread_0 starts and calls mre.WaitOne()
'Thread_1 starts and calls mre.WaitOne()
'Thread_2 starts and calls mre.WaitOne()
'
'When all three threads have started, press Enter to call Set()
'to release all the threads.
'
'
'Thread_2 ends.
'Thread_0 ends.
'Thread_1 ends.
'
'When a ManualResetEvent is signaled, threads that call WaitOne()
'do not block. Press Enter to show this.
'
'
'Thread_3 starts and calls mre.WaitOne()
'Thread_3 ends.
'Thread_4 starts and calls mre.WaitOne()
'Thread_4 ends.
'
'Press Enter to call Reset(), so that threads once again block
'when they call WaitOne().
'
'
'Thread_5 starts and calls mre.WaitOne()
'
'Press Enter to call Set() and conclude the demo.
'
'Thread_5 ends.
注解
使用 ManualResetEvent
、AutoResetEvent和 EventWaitHandle 进行线程交互(或线程信号)。 有关详细信息,请参阅 同步基元概述 一文中的 线程交互或信号 部分。
当线程开始必须在其他线程继续之前完成的活动时,它将调用 ManualResetEvent.Reset 以将 ManualResetEvent
置于非信号状态。 可以将此线程视为控制 ManualResetEvent
。 调用 manualResetEvent.WaitOne 块
发出信号后,ManualResetEvent
保持信号,直到通过调用 Reset() 方法手动重置。 也就是说,调用 WaitOne 立即返回。
可以通过将布尔值传递给构造函数来控制 ManualResetEvent
的初始状态:如果发出初始状态,则 true
,否则 false
。
ManualResetEvent
还可用于 static
WaitAll 和 WaitAny 方法。
从 .NET Framework 版本 2.0 开始,ManualResetEvent 派生自 EventWaitHandle 类。 ManualResetEvent 在功能上等效于使用 EventResetMode.ManualReset创建的 EventWaitHandle。
注意
与 ManualResetEvent 类不同,EventWaitHandle 类提供对命名系统同步事件的访问权限。
从 .NET Framework 版本 4.0 开始,System.Threading.ManualResetEventSlim 类是 ManualResetEvent的轻型替代方法。
构造函数
ManualResetEvent(Boolean) |
使用布尔值初始化 ManualResetEvent 类的新实例,该值指示是否将初始状态设置为信号。 |
字段
WaitTimeout |
指示在发出任何等待句柄之前,WaitAny(WaitHandle[], Int32, Boolean) 操作超时。 此字段为常量。 (继承自 WaitHandle) |
属性
Handle |
已过时.
已过时.
获取或设置本机操作系统句柄。 (继承自 WaitHandle) |
SafeWaitHandle |
获取或设置本机操作系统句柄。 (继承自 WaitHandle) |
方法
Close() |
释放当前 WaitHandle持有的所有资源。 (继承自 WaitHandle) |
CreateObjRef(Type) |
创建一个对象,其中包含生成用于与远程对象通信的代理所需的所有相关信息。 (继承自 MarshalByRefObject) |
Dispose() |
释放 WaitHandle 类的当前实例使用的所有资源。 (继承自 WaitHandle) |
Dispose(Boolean) |
在派生类中重写时,释放 WaitHandle使用的非托管资源,并选择性地释放托管资源。 (继承自 WaitHandle) |
Equals(Object) |
确定指定的对象是否等于当前对象。 (继承自 Object) |
GetAccessControl() |
获取一个 EventWaitHandleSecurity 对象,该对象表示由当前 EventWaitHandle 对象表示的命名系统事件的访问控制安全性。 (继承自 EventWaitHandle) |
GetHashCode() |
用作默认哈希函数。 (继承自 Object) |
GetLifetimeService() |
已过时.
检索控制此实例的生存期策略的当前生存期服务对象。 (继承自 MarshalByRefObject) |
GetType() |
获取当前实例的 Type。 (继承自 Object) |
InitializeLifetimeService() |
已过时.
获取生存期服务对象来控制此实例的生存期策略。 (继承自 MarshalByRefObject) |
MemberwiseClone() |
创建当前 Object的浅表副本。 (继承自 Object) |
MemberwiseClone(Boolean) |
创建当前 MarshalByRefObject 对象的浅表副本。 (继承自 MarshalByRefObject) |
Reset() |
将事件的状态设置为非对齐状态,这会导致线程阻止。 |
Reset() |
将事件的状态设置为非对齐状态,导致线程被阻止。 (继承自 EventWaitHandle) |
Set() |
将事件的状态设置为信号,这允许一个或多个等待的线程继续。 |
Set() |
将事件的状态设置为信号,允许一个或多个等待线程继续。 (继承自 EventWaitHandle) |
SetAccessControl(EventWaitHandleSecurity) |
设置命名系统事件的访问控制安全性。 (继承自 EventWaitHandle) |
ToString() |
返回一个表示当前对象的字符串。 (继承自 Object) |
WaitOne() |
阻止当前线程,直到当前 WaitHandle 收到信号。 (继承自 WaitHandle) |
WaitOne(Int32) |
阻止当前线程,直到当前 WaitHandle 接收信号,使用 32 位有符号整数指定时间间隔(以毫秒为单位)。 (继承自 WaitHandle) |
WaitOne(Int32, Boolean) |
阻止当前线程,直到当前 WaitHandle 收到信号,使用 32 位有符号整数指定时间间隔,并指定是否在等待之前退出同步域。 (继承自 WaitHandle) |
WaitOne(TimeSpan) |
阻止当前线程,直到当前实例收到信号,使用 TimeSpan 指定时间间隔。 (继承自 WaitHandle) |
WaitOne(TimeSpan, Boolean) |
阻止当前线程,直到当前实例收到信号,使用 TimeSpan 指定时间间隔,并指定是否在等待之前退出同步域。 (继承自 WaitHandle) |
显式接口实现
IDisposable.Dispose() |
此 API 支持产品基础结构,不能在代码中直接使用。 释放 WaitHandle使用的所有资源。 (继承自 WaitHandle) |
扩展方法
GetAccessControl(EventWaitHandle) |
返回指定 |
SetAccessControl(EventWaitHandle, EventWaitHandleSecurity) |
设置指定事件等待句柄的安全描述符。 |
GetSafeWaitHandle(WaitHandle) |
获取本机操作系统等待句柄的安全句柄。 |
SetSafeWaitHandle(WaitHandle, SafeWaitHandle) |
设置本机操作系统等待句柄的安全句柄。 |
适用于
线程安全性
此类是线程安全的。
另请参阅
- WaitHandle
- 托管线程处理
- 同步基元 概述