AutoResetEvent 类讲解

表示线程同步事件在一个等待线程释放后收到信号时自动重置。 此类不能被继承。

[System.Runtime.InteropServices.ComVisible(true)]
public sealed class AutoResetEvent : System.Threading.EventWaitHandle

以下示例演示如何在AutoResetEventSet每次用户按 Enter 键时调用基类上的 方法 () 一次释放一个线程。 该示例启动三个 AutoResetEvent 线程,等待在信号状态下创建的 。 第一个线程会立即释放,因为 AutoResetEvent 已处于信号状态。 这会将 AutoResetEvent 重置为非信号状态,以便后续线程阻塞。 在用户按 Enter 键一次释放一个线程之前,不会释放被阻止的线程。

从第一个 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.
 */

将 AutoResetEvent、 ManualResetEvent和 EventWaitHandle 用于线程交互 (或线程信号) 。 有关详细信息,请参阅同步基元概述一文的线程交互或信号部分。
重要

此类型实现 IDisposable 接口。 在使用完类型后,您应直接或间接释放类型。 若要直接释放类型,请在 try/catch 块中调用其 Dispose 方法。 若要间接释放类型,请使用 using(在 C# 中)或 Using(在 Visual Basic 中)等语言构造。 有关详细信息,请参阅 IDisposable 接口主题中的“使用实现 IDisposable 的对象”一节。

线程通过调用 AutoResetEvent.WaitOne 来等待信号。 AutoResetEvent如果 处于非信号状态,线程将阻止,直到调用 AutoResetEvent.Set。

调用 Set 信号 AutoResetEvent 以释放等待的线程。 AutoResetEvent 在释放单个等待线程之前保持信号,然后自动返回到非信号状态。 如果没有线程在等待,状态将无限期保持信号。

如果线程在 处于信号状态时AutoResetEvent调用 WaitOne ,则线程不会阻止。 立即 AutoResetEvent 释放线程并返回到非信号状态。

重要

不能保证每次调用 Set 方法都会释放线程。 如果两个调用在一起太近,因此第二次调用在线程释放之前发生,则只释放一个线程。 就好像第二次调用没有发生。 此外,如果在 Set 没有线程等待且 AutoResetEvent 已发出信号时调用 ,则调用不起作用。

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

AutoResetEvent还可以与 和 方法一起使用staticWaitAll。WaitAny

从 .NET Framework 版本 2.0 开始,AutoResetEvent派生自新EventWaitHandle类。 在 AutoResetEvent 功能上等效于 EventWaitHandle 使用 EventResetMode.AutoReset创建的

你可能感兴趣的:(c#)