AutoResetEvent 允许线程通过发信号互相通信。 通常,当线程需要独占访问资源时使用该类。
线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。 如果 AutoResetEvent 为非终止状态,则线程会被阻止,并等待当前控制资源的线程通过调用 Set 来通知资源可用。
调用 Set 向 AutoResetEvent 发信号以释放等待线程。 AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。 如果没有任何线程在等待,则状态将无限期地保持为终止状态。
如果当 AutoResetEvent 为终止状态时线程调用 WaitOne,则线程不会被阻止。 AutoResetEvent 将立即释放线程并返回到非终止状态。
重要事项 |
|---|
|
不能保证对 Set 方法的每次调用都释放线程。 如果两次调用十分接近,以致在线程释放之前便已发生第二次调用,则只释放一个线程。 就像第二次调用并未发生一样。 另外,如果在调用 Set 时不存在等待的线程且 AutoResetEvent 已终止,则该调用无效。 |
可以通过将一个布尔值传递给构造函数来控制 AutoResetEvent 的初始状态:如果初始状态为终止状态,则为 true;否则为 false。
AutoResetEvent 也可以同 staticWaitAll 和 WaitAny 方法一起使用。
示例
下面的示例演示如何通过(对基类)调用 Set 方法使用 AutoResetEvent 一次释放一个线程,每次用户需按 “Enter” 键。 该示例将启动三个线程,这些线程等待终止状态中的已创建的 AutoResetEvent。 由于 AutoResetEvent 已处于终止状态,所以立即释放第一个线程。 这将重置 AutoResetEvent 为非信号状态,从而随后的线程阻塞。 被阻止的线程只能让用户通过按下“输入”键一个个的释放。
这些线程从第一个 AutoResetEvent 中释放后,它们等待在非终止状态中创建的其他 AutoResetEvent。 所有三个线程阻止,所以必须调用 Set 方法三次以将其释放。
using System;
using System.Threading;
// Visual Studio: Replace the default class in a Console project with
// the following class.
class Example
{
private static AutoResetEvent event_1 = new AutoResetEvent(true);
private static AutoResetEvent event_2 = new AutoResetEvent(false);
static void Main()
{
Console.WriteLine("Press Enter to create three threads and start them.\r\n" +
"The threads wait on AutoResetEvent #1, which was created\r\n" +
"in the signaled state, so the first thread is released.\r\n" +
"This puts AutoResetEvent #1 into the unsignaled state.");
Console.ReadLine();
for (int i = 1; i < 4; i++)
{
Thread t = new Thread(ThreadProc);
t.Name = "Thread_" + i;
t.Start();
}
Thread.Sleep(250);
for (int i = 0; i < 2; i++)
{
Console.WriteLine("Press Enter to release another thread.");
Console.ReadLine();
event_1.Set();
Thread.Sleep(250);
}
Console.WriteLine("\r\nAll threads are now waiting on AutoResetEvent #2.");
for (int i = 0; i < 3; i++)
{
Console.WriteLine("Press Enter to release a thread.");
Console.ReadLine();
event_2.Set();
Thread.Sleep(250);
}
// Visual Studio: Uncomment the following line.
//Console.Readline();
}
static void ThreadProc()
{
string name = Thread.CurrentThread.Name;
Console.WriteLine("{0} waits on AutoResetEvent #1.", name);
event_1.WaitOne();
Console.WriteLine("{0} is released from AutoResetEvent #1.", name);
Console.WriteLine("{0} waits on AutoResetEvent #2.", name);
event_2.WaitOne();
Console.WriteLine("{0} is released from AutoResetEvent #2.", name);
Console.WriteLine("{0} ends.", name);
}
}
/* This example produces output similar to the following:
Press Enter to create three threads and start them.
The threads wait on AutoResetEvent #1, which was created
in the signaled state, so the first thread is released.
This puts AutoResetEvent #1 into the unsignaled state.
Thread_1 waits on AutoResetEvent #1.
Thread_1 is released from AutoResetEvent #1.
Thread_1 waits on AutoResetEvent #2.
Thread_3 waits on AutoResetEvent #1.
Thread_2 waits on AutoResetEvent #1.
Press Enter to release another thread.
Thread_3 is released from AutoResetEvent #1.
Thread_3 waits on AutoResetEvent #2.
Press Enter to release another thread.
Thread_2 is released from AutoResetEvent #1.
Thread_2 waits on AutoResetEvent #2.
All threads are now waiting on AutoResetEvent #2.
Press Enter to release a thread.
Thread_2 is released from AutoResetEvent #2.
Thread_2 ends.
Press Enter to release a thread.
Thread_1 is released from AutoResetEvent #2.
Thread_1 ends.
Press Enter to release a thread.
Thread_3 is released from AutoResetEvent #2.
Thread_3 ends.
*/
重要事项
浙公网安备 33010602011771号