ManualResetEvent 类

定义

表示必须手动重置信号的线程同步事件。 无法继承此类。

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 工作。 该示例以处于无对齐状态的 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.

注解

使用 ManualResetEventAutoResetEventEventWaitHandle 进行线程交互(或线程信号)。 有关详细信息,请参阅 同步基元概述 一文中的 线程交互或信号 部分。

当线程开始必须在其他线程继续之前完成的活动时,它将调用 ManualResetEvent.Reset 以将 ManualResetEvent 置于非信号状态。 可以将此线程视为控制 ManualResetEvent。 调用 manualResetEvent.WaitOne 块 线程,等待信号。 当控制线程完成活动时,它会调用 ManualResetEvent.Set 来指示等待线程可以继续。 所有等待的线程都会释放。

发出信号后,ManualResetEvent 保持信号,直到通过调用 Reset() 方法手动重置。 也就是说,调用 WaitOne 立即返回。

可以通过将布尔值传递给构造函数来控制 ManualResetEvent 的初始状态:如果发出初始状态,则 true,否则 false

ManualResetEvent 还可用于 staticWaitAllWaitAny 方法。

从 .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)

返回指定 handle的安全描述符。

SetAccessControl(EventWaitHandle, EventWaitHandleSecurity)

设置指定事件等待句柄的安全描述符。

GetSafeWaitHandle(WaitHandle)

获取本机操作系统等待句柄的安全句柄。

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

设置本机操作系统等待句柄的安全句柄。

适用于

线程安全性

此类是线程安全的。

另请参阅