一:终止状态和非终止状态

    首先说说线程的终止状态和非终止状态。AutoResetEvent和ManualResetEvent的构造函数中,都有bool变量来指明线程的终止状态和非终止状态。true表示终止状态(个人理解也就是可运行状态,根据理解应该是该线程的阻塞终止了),false表示非终止状态。

        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); //Thread.Sleep(Int32)是批当前进程挂起3000毫秒,与线程t1是一点关系也没有的。
_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 允许线程通过发信号互相通信。 通常,当线程需要独占访问资源时使用该类。

线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。 如果 AutoResetEvent 为非终止状态,则线程会被阻止,并等待当前控制资源的线程通过调用 Set来通知资源可用。

调用 Set 向 AutoResetEvent 发信号以释放等待线程。 AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。 如果没有任何线程在等待,则状态将无限期地保持      为终止状态。如果当 AutoResetEvent 为终止状态时线程调用 WaitOne,则线程不会被阻止。 AutoResetEvent 将立即释放线程并返回到非终止状态


     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的原因。为了更加充分的验证Manua lResetEvent的这点特性,我们再来看代码片段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()。

  

C#AutoResetEvent和ManualResetEvent的区别的更多相关文章

  1. 线程中AutoResetEvent与ManualResetEvent的区别

    线程之间的通信是通过发信号来进行沟通的.. ManualResetEvent发送Set信后后,需要手动Reset恢复初始状态.而对于AutoResetEvent来说,当发送完毕Set信号后,会自动Re ...

  2. 个人对AutoResetEvent和ManualResetEvent的理解(转载)

    仅个人见解,不对之处请指正,谢谢. 一.作用 AutoResetEvent和ManualResetEvent可用于控制线程暂停或继续,拥有重要的三个方法:WaitOne.Set和Reset. 这三个方 ...

  3. 线程同步 –AutoResetEvent和ManualResetEvent

    上一篇介绍了通过lock关键字和Monitor类型进行线程同步,本篇中就介绍一下通过同步句柄进行线程同步. 在Windows系统中,可以使用内核对象进行线程同步,内核对象由系统创建并维护.内核对象为内 ...

  4. 个人对AutoResetEvent和ManualResetEvent的理解

    一.作用 AutoResetEvent和ManualResetEvent可用于控制线程暂停或继续,拥有重要的三个方法:WaitOne.Set和Reset. 这三个方法的官方定义并不好理解,什么终止.非 ...

  5. [转]个人对AutoResetEvent和ManualResetEvent的理解

    仅个人见解,不对之处请指正,谢谢. 一.作用 AutoResetEvent和ManualResetEvent可用于控制线程暂停或继续,拥有重要的三个方法:WaitOne.Set和Reset. 这三个方 ...

  6. AutoResetEvent和ManualResetEvent(多线程操作)

    摘自风中灵药的博客:https://www.cnblogs.com/qingyun163/archive/2013/01/05/2846633.html#!comments AutoResetEven ...

  7. AutoResetEvent与ManualResetEvent区别

    本文来自:http://www.360doc.com/content/10/1126/10/3267996_72536817.shtml 在.Net多线程编程中,AutoResetEvent和Manu ...

  8. C#多线程同步事件及等待句柄AutoResetEvent 和 ManualResetEvent

    最近捣鼓了一下多线程的同步问题,发现其实C#关于多线程同步事件处理还是很灵活,这里主要写一下,自己测试的一些代码,涉及到了AutoResetEvent 和 ManualResetEvent,当然还有也 ...

  9. 多线程间通信之AutoResetEvent和ManualResetEvent的原理分析

    AutoResetEvent 允许线程通过发信号互相通信. 通常,当线程需要独占访问资源时使用该类. 线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号. 如果 AutoRe ...

随机推荐

  1. asp.net 操作word

    参考一:点击这里 参考二:点击这里 参考三:点击这里 using System; using System.Web.Security; using Microsoft.Office.Interop.W ...

  2. 新装Centos常见问题及解决方案

    1.可以ping通,但无法通过ssh连接虚拟机的解决方案 虚拟机上装了一个 Linux 玩玩, 但在启动 Linux 后,在 Windows 中通过 Xshell 以 SSH 方式连接到 Linux ...

  3. android 开发 socket发送会有部分乱码,串码,伴随着数据接收不完整

    场景: 客户端A.B,A向B发送json字符串后紧接着发送文件,B接收到文件后才返回消息. 环境:android.使用的是原始的write 和read (若使用的是writeUTF不会出现此问题.)需 ...

  4. 【Symmetric Tree】cpp

    题目: Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). F ...

  5. Oracle中定义package以及存储过程的使用

    使用scott账户下的dept表: select * from dept order by deptno; 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 S ...

  6. ASP.NET MVC 如何在一个同步方法(非async)方法中等待async方法

    问题 首先,在ASP.NET MVC 环境下对async返回的Task执行Wait()会导致线程死锁.例: public ActionResult Asv2() { //dead lock var t ...

  7. weiapi2.2 HelpPage自动生成接口说明文档和接口测试功能

    在开发Webapi项目时每写完一个方法时,是不是需要添加相应的功能说明和测试案例呢?为了更简单方便的写说明接口文档和接口测试HelpPage提供了一个方便的途径. 她的大致原理是:在编译时会生成.dl ...

  8. DOM中事件绑定补充方法

    先将上一篇文章中提到的为元素增加事件的方法和移除事件的方法拿过来: <span style="font-size:18px;">//跨浏览器添加事件 function ...

  9. matrix_last_acm_3

    the first CCPC   password 123 A http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97380#problem/ ...

  10. Nsdate的各种常用操作

    // //  NVDate.h // //  Created by Noval Agung Prayogo on 2/5/14. //  Copyright (c) 2014 Noval Agung ...