首页 > 代码库 > AutoResetEvent详解
AutoResetEvent详解
在MSDN中,它的解释为:通知正在等待的线程已发生事件。无法继承此类(密封类)。
AutoResetEvent 允许线程通过发信号进行相互通信,例如发Set信号,让正在WaitOne等待信号着的线程开启继续执行。通常,此通信涉及线程需要独立访问的资源。
线程通过调用 AutoResetEvent 上的WaitOne来等待信号。如果 AutoResetEvent 处于非终止状态,则该线程阻塞,并等待当前控制资源的线程通过调用 Set发出资源可用的信号。
调用 Set 向 AutoResetEvent 发信号以释放等待线程,这里释放的是有WaitOne等待着的随机的某一个线程 ,而不是所有有WaitOne等待信号的线程,此时AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。如果没有任何线程在等待(没有一个线程有WaitOne等待信号),则状态将无限期地保持为终止状态。
它可以通过将一个布尔值传递给构造函数来控制 AutoResetEvent 的初始状态,如果初始状态为终止状态,则为 true;否则为 false。
示例代码:
实现类源码:
class AutoResetEventTest { private AutoResetEvent are; public AutoResetEventTest() { this.are = new AutoResetEvent(false); } /// <summary> /// 放行等待的线程 /// </summary> public void Set() { this.are.Set(); } /// <summary> /// 暂停正在等待的线程 /// </summary> public void Reset() { this.are.Reset(); } /// <summary> /// 启动N个线程,可以手动传入参数指定启动几个线程 /// </summary> /// <param name="threadNumber"></param> public void CreateThreads(int threadNumber) { Thread[] threads = new Thread[threadNumber]; for (int i = 0; i < threadNumber; i++) { threads[i] = new Thread(new ThreadStart(Run)); threads[i].Start(); } } /// <summary> /// 正在等待着的线程,该线程打印出线程ID /// </summary> private void Run() { string threadId = string.Empty; try { while (true) { // 阻塞当前线程 this.are.WaitOne(); threadId = Thread.CurrentThread.ManagedThreadId.ToString(); Console.WriteLine("Run---Thread(" + threadId + ") is running..."); Thread.Sleep(3000); } } catch (Exception ex)//异常处理 { Console.WriteLine("Run---Thread(" + threadId + ") Error happend!:" + ex.Message.ToString()); } } }
主函数源码:
在控制台界面上输入run会看到某个等待着的线程被开启:
class Program { static void Main(string[] args) { Console.WriteLine("**********************************"); Console.WriteLine("请输入\"run\"开启正在等待着的线程..."); Console.WriteLine("********************************\r\n"); AutoResetEventTest test = new AutoResetEventTest(); test.CreateThreads(10); while (true) { string input = Console.ReadLine(); if (input.Trim().ToLower() == "run") { Console.WriteLine("WaitOne等待着的某个线程开启运行..."); test.Set(); } } } }
运行结果:
当输入一次run时,显示如下:
由于初始化AutoResetEvent 事件为false,则该事件处于非终止状态,故所有等待着的线程在没有Set信号到来时,都将暂停运行,当输入一次run,调用AutoResetEvent 的Set方法,将会随机开启某一个正在等待着的线程,当该等待着的线程被释放,则AutoResetEvent 自动的变为非终止状态,其余的等待线程想要开启就必须等待再一次Set信号。
当输入多次run时,显示结果如下:
每输入一次run都会调用AutoResetEvent 事件的Set方法,将会随机开启某一个正在等待着的线程,当这个线程被释放后,则AutoResetEvent 事件会自动的置为非终止状态,那么刚刚被开启的线程将会再次等待,直到等待下一次Set信号将它开启。
假如我们初始化将AutoResetEvent 事件设置为true,则在控制台下会看到如下结果:
这是因为初始化将AutoResetEvent 事件设置为true,则它会处于终止状态,那么会初次开启某个线程,当这个等待着的线程被释放时,则会自动将AutoResetEvent 设置成非终止状态,直到有Set信号给某个等待着的线程,才会开启这个等待着的线程。
如下:
再一次输入run,
调用AutoResetEvent 的Set方法,将会随机的开启某一个正在等待着的线程,线程释放完毕后会自动将AutoResetEvent 置为非终止状态,所以每当run一次只能看到一次随机等待的线程在跑。
AutoResetEvent详解