首先说说线程的终止状态和非终止状态。AutoResetEvent和ManualResetEvent的构造函数中,都有bool变量来指明线程的终止状态和非终止状态。true表示终止状态,false表示非终止状态。看代码片段1:
代码片段1:
AutoResetEvent _autoResetEvent = new AutoResetEvent(false);
private void BT_Temp_Click(object sender, RoutedEventArgs e)
{
Thread t1 = new Thread(this.Thread1Foo);
t1.Start();
Thread.Sleep(3000);
_autoResetEvent.Set();
}
void Thread1Foo()
{
_autoResetEvent.WaitOne();
MessageBox.Show("t1 end");
}
这段代码的执行结果,就是3秒钟过后,弹出“t1 end”。
而如果把:
AutoResetEvent _autoResetEvent = new AutoResetEvent(false);
改为:
AutoResetEvent _autoResetEvent = new AutoResetEvent(true);
则“t1 end”将会立刻弹出。
也就是说,在终止状态中,_autoResetEvent.WaitOne()是不会起到阻滞工作线程的作用的。(PS:ManualResetEvent也同样)
二:AutoResetEvent和ManualResetEvent的区别
接下来,再来看看AutoResetEvent和ManualResetEvent的区别。我们看代码段2和代码段3:
代码段2:
AutoResetEvent _autoResetEvent = new AutoResetEvent(false);
private void BT_Temp_Click(object sender, RoutedEventArgs e)
{
Thread t1 = new Thread(this.Thread1Foo);
t1.Start();
Thread t2 = new Thread(this.Thread2Foo);
t2.Start();
Thread.Sleep(3000);
_autoResetEvent.Set();
}
void Thread1Foo()
{
_autoResetEvent.WaitOne();
MessageBox.Show("t1 end");
}
void Thread2Foo()
{
_autoResetEvent.WaitOne();
MessageBox.Show("t2 end");
}
该段代码运行的效果是,过3秒后,要么弹出“t1 end”,要么弹出“t2 end”,不会两个都弹出。也就是说,其中一个进行将会结束,而另一个进程永远不会结束。
代码段3:
ManualResetEvent _menuRestEvent = new ManualResetEvent(false);
private void BT_Temp_Click(object sender, RoutedEventArgs e)
{
Thread t1 = new Thread(this.Thread1Foo);
t1.Start();
Thread t2 = new Thread(this.Thread2Foo);
t2.Start();
Thread.Sleep(3000);
_menuRestEvent.Set();
}
void Thread1Foo()
{
_menuRestEvent.WaitOne();
MessageBox.Show("t1 end");
}
void Thread2Foo()
{
_menuRestEvent.WaitOne();
MessageBox.Show("t2 end");
}
该段代码运行的效果是,过3秒后,“t1 end”和“t2 end”,两个都被弹出。也就是说,两个进程都结束了。
这个特性就是说,AutoResetEvent只会给一个线程发送信号,而不会给多个线程发送信号。在我们需要同步多个线程的时候,就只能采用ManualResetEvent了。至于深层次的原因是,AutoResetEvent在set()之后,会将线程状态自动置为false,而ManualResetEvent在Set()后,线程的状态就变为true了,必须手动ReSet()之后,才会重新将线程置为false。这也就是为什么他们的名字一个为Auto,一个为Manual的原因。为了更加充分的验证ManualResetEvent的这点特性,我们再来看代码片段4
代码片段4:
ManualResetEvent _menuRestEvent = new ManualResetEvent(false);
private void BT_Temp_Click(object sender, RoutedEventArgs e)
{
Thread t1 = new Thread(this.Thread1Foo);
t1.Start();
Thread t2 = new Thread(this.Thread2Foo);
t2.Start();
Thread.Sleep(3000);
_menuRestEvent.Set();
//_menuRestEvent.Reset();
}
void Thread1Foo()
{
_menuRestEvent.WaitOne();
MessageBox.Show("t1 step1 end");
//睡1S,用于等待主线程_menuRestEvent.Reset();
Thread.Sleep(1000);
_menuRestEvent.WaitOne();
MessageBox.Show("t1 step2 end");
}
void Thread2Foo()
{
_menuRestEvent.WaitOne();
MessageBox.Show("t2 step1 end");
//睡1S,用于等待主线程_menuRestEvent.Reset();
Thread.Sleep(1000);
_menuRestEvent.WaitOne();
MessageBox.Show("t2 step2 end");
}
在代码片段4中,我们对//_menuRestEvent.Reset()进行了注释,也就是说, _menuRestEvent.Set()后,线程的状态就是true状态的,程序运行的结果是"t1 step1 end"、"t1 step2 end"、"t1 step2 end"、"t2 step2 end"在3秒之后全部弹出。
而如果我们将//_menuRestEvent.Reset()的注释去掉,会发现"t1 step2 end"和"t2 step2 end"永远不会弹出。除非我们在主线程中再次对_menuRestEvent进行Set()。
分享到:
相关推荐
引入命名空间: using System.Threading; AutoResetEvent: autoResetEvent.WaitOne();//运行完后,**自动将事件...ManualResetEvent: manulResetEvent.WaitOne();//运行完后,**不会自动将事件状态设置为无信号**
在多线程编程中,`AutoResetEvent` 和 `ManualResetEvent` 是两种重要的同步原语,用于控制线程间的协作和同步。本压缩包文件提供了关于这两种事件类型的实例代码,帮助开发者理解它们的工作原理和用法。 首先,让...
最近捣鼓了一下多线程的同步问题,发现其实C#关于多线程同步事件处理还是很灵活,这里主要写一下,自己测试的一些代码,涉及到了AutoResetEvent 和 ManualResetEvent,当然还有也简要提了一下System.Threading....
AutoResetEvent和ManualResetEvent是事件对象,用于线程间的通信和同步,其中AutoResetEvent在释放一个等待线程后自动重置,而ManualResetEvent则需要手动重置。 在设计多线程程序时,应当避免使用Thread.Abort来...
搞过C#多线程的人对其中的AutoResetEvent和ManualResetEvent这两个类都理解,其中的WaitOne()方法和Set()以及Reset()方法在线程同步当中用的是比较多的。 AutoResetEvent :当某个线程执行到WaitOne()方法时,该线程...
例如,AutoResetEvent和ManualResetEvent分别用于单次信号和多次信号。这些事件可以与其他同步机制结合使用,以实现复杂的同步策略。 等待句柄是Windows操作系统级别的同步机制,如Mutex、Semaphore和Event。Mutex...
有两类EventWaitHandle:AutoResetEvent和ManualResetEvent。AutoResetEvent在事件触发后自动重置,只有一个等待的线程可以继续执行;而ManualResetEvent则需要手动调用Reset() 方法来重置事件状态,因此可以唤醒多...
6. **EventWaitHandle、AutoResetEvent 和 ManualResetEvent**: 这些事件类用于线程间的通信,线程等待事件触发后才能继续执行。`AutoResetEvent`在一个信号后自动重置,而`ManualResetEvent`需要手动重置。 7. *...
##### AutoResetEvent 和 ManualResetEvent 这两种类提供了基于事件的等待机制,允许一个或多个线程等待某个事件的发生。 ```csharp AutoResetEvent autoEvent = new AutoResetEvent(false); void WaitMethod() {...
6. **AutoResetEvent和ManualResetEvent**:这两个是`EventWaitHandle`的子类,用于创建事件。`AutoResetEvent`在释放后自动重置,只允许一个线程通过;`ManualResetEvent`则需要手动重置,可以允许多个线程通过。 ...
包括AutoResetEvent和ManualResetEvent,用于线程间的信号通信。 2.5.1 AutoResetEvent ```csharp AutoResetEvent autoEvent = new AutoResetEvent(false); autoEvent.Set(); // 释放信号 autoEvent.WaitOne(); //...
- AutoResetEvent和ManualResetEvent是线程同步事件,可以用来让一个线程等待另一个线程完成某个操作。 - WaitHandle类的WaitOne()方法用于线程等待,Signal()方法用于唤醒等待的线程。 6. **异步编程模型**: -...
例如,AutoResetEvent和ManualResetEvent可作为线程间等待和通知的信号。 6. **线程状态与优先级**:每个线程都有自己的生命周期和状态(如新建、运行、等待、停止等)。Thread类提供了属性和方法来获取或设置线程...
EventWaitHandle类提供了一种线程间的通信方式,如AutoResetEvent和ManualResetEvent,它们可以用来控制线程何时继续执行。WaitOne方法使线程等待事件发生,Set方法则释放等待的线程。 十、线程挂起与恢复 Thread类...
在本篇文章中,我们将探讨基于内核模式构造的线程同步方式,包括事件、信号量,以及WaitHandle、AutoResetEvent和ManualResetEvent这三种重要的同步工具。 一、理论 线程同步可以分为用户模式构造和内核模式构造。...
与AutoResetEvent的区别在于,ManualResetEvent在释放一次后不会自动重置,需要开发者手动调用Reset方法来恢复到未设置状态。 **初始化ManualResetEvent** ManualResetEvent的构造函数允许我们初始化其初始状态。...
与`AutoResetEvent`不同,`ManualResetEvent`在释放一次后不会自动重置,需要手动调用`Reset()`方法来恢复未启动状态。 **一、构造函数** `ManualResetEvent`有两个构造函数: 1. `ManualResetEvent(false)`:初始...
本文将重点解析多线程中的线程同步机制,特别是`AutoResetEvent`和`ManualResetEvent`这两种关键同步对象的特性和使用场景。 #### 终止状态与非终止状态:理解线程的生命周期 在多线程编程中,线程的生命周期至关...
Mutex(互斥锁)和AutoResetEvent(自动重置事件)是.NET框架提供的两种工具,用于解决这些问题。 Mutex是一种全局资源锁,它允许在任何时间只有一个线程访问特定的资源或代码段。在C#中,我们可以使用Mutex的构造...
3. **手动重置**:与`ManualResetEvent`不同,`AutoResetEvent`只允许一个线程通过,如果需要多次触发,需要再次调用`Set()`方法。 ### 四、AutoResetEvent的使用 在C#中,我们可以这样使用`AutoResetEvent`: ``...