Reset(): 当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时, 它调用 Reset 以将 ManualResetEvent 置于非终止状态。此线程可被视为控制 ManualResetEvent。

为了把状态修改为无信号的,必须调用ReSet()方法。

WaitOne(): 调用ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号。

Set ()当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。Set将事件状态设置为终止状态,允许一个或多个等待线程继续。

为了把状态修改为有信号的,必须调用Set()方法。

ManualResetEvent对象只能拥有两种状态之一:有信号(True)或无信号(false)。ManualResetEvent类继承于WaitHandle类,其构造函数的参数可确定对象的初始状态。

Set()和Reset()方法返回一个布尔值,表示是否进行了成功的修改。

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ManualResetshiyan
{
    class Program
    {
        static void Main(string[] args)
        {
            ManualResetEvent mansig;
            mansig = new ManualResetEvent(false);
            Console.WriteLine("ManualResetEvent Before WaitOne");
            bool b = mansig.WaitOne(1000, true);
            Console.WriteLine("ManualResetEvent After WaitOne" + b);
            Console.ReadLine();
        }
    }
}
 

上面的例子中,构造了false值的ManualResetEvent对象,布尔值False把ManualResetEvent对象的初始状态设置为无信号。接着调用基类WaigHandle的WaitOne()方法。程序块在WaitOne()方法中暂停一秒,然后因为超时而退出。ManualResetEvent的状态仍然是False,因而WaitOne()返回的布尔值b是False。

下面的例子把有信号改为无信号,调用ReSet()方法,Set()方法。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Threading;
  5. namespace 同步
  6. {
  7. class Program
  8. {
  9. static void Main(string[] args)
  10. {
  11. ManualResetEvent mansig;
  12. mansig = new ManualResetEvent(true);
  13. bool state = mansig.WaitOne(9000, true);
  14. Console.WriteLine("ManualResetEvent After WaitOne" + state);
  15. mansig.Reset();
  16. state = mansig.WaitOne(9000, true);
  17. Console.WriteLine("ManualResetEvent After WaitOne" + state);
  18. mansig.Set();
  19. state = mansig.WaitOne(9000, true);
  20. Console.WriteLine("ManualResetEvent After WaitOne" + state);
  21. }
  22. }
  23. }

在ManualReset中,MnualTResetEvent对象的构造函数将其状态设置为有信号(true),结果,线程不在第一个

WaitOne()方法中等待,并返回True值。接着,ManualResetEvent对象的状态重新设置为无信号的(false),于是线程在超时之前必须等待5秒,调用Set()方法后也不用等待。

下面在看一个程序:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Threading;
  5. namespace 同步实验
  6. {
  7. class Program
  8. {    ///
  9. /// ManualResetEvent建立时是把false作为start的初始状态,这个类用于通知另一个线程,让它等待一个或多个线程。
  10. /// 如这个例子中,等待线程thread1线程调用mre.WaitOne(), 用于发信号的线程调用mre.Set().
  11. ///
  12. public static ManualResetEvent mre = new ManualResetEvent(false);
  13. public static void trmain()
  14. {
  15. Thread tr = Thread.CurrentThread;
  16. Console.WriteLine(tr.Name + " 开始第一波等待");
  17. mre.WaitOne();   //等到什么时候呢?等到mre.Set()被调用
  18. Console.WriteLine(tr.Name + " 第一波启动t");
  19. mre.Reset();   //再次重置
  20. Console.WriteLine(tr.Name + " 开始第二波等待");
  21. mre.WaitOne();   //再次等待
  22. Console.WriteLine(tr.Name + " 第二波启动");
  23. for (int x = 0; x < 10; x++)
  24. {
  25. Thread.Sleep(1000);
  26. Console.WriteLine(tr.Name + ": " + x);
  27. }
  28. }
  29. static void Main(string[] args)
  30. {
  31. Thread thrd1 = new Thread(new ThreadStart(trmain));
  32. thrd1.Name = "thread1";
  33. thrd1.Start();
  34. Thread thrd2 = new Thread(new ThreadStart(trmain));
  35. thrd2.Name = "thread2";
  36. thrd2.Start();
  37. for (int x = 0; x < 10; x++)
  38. {
  39. Thread.Sleep(900);
  40. Console.WriteLine("Main :" + x);
  41. if (5 == x)
  42. {
  43. mre.Set();   //子线程的mre.WaitOne()可以执行了。第一次等待进程
  44. //;   //如果什么都不做呢,mre.Wait()那个线程就一直等在那里了?
  45. }
  46. }
  47. while (thrd1.IsAlive)
  48. {
  49. Thread.Sleep(1000);
  50. Console.WriteLine("Main: waiting for thread to stop...");
  51. mre.Set();   //第二次通知等待进程
  52. }
  53. }
  54. }
  55. }

下面在看一个关于ManualResetEvent waitany的程序:

waitany一直等到有信号 才开始执行下面的语句.

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Threading;
  5. namespace 同步实验
  6. {
  7. class Program
  8. {
  9. public static ManualResetEvent m_eventTemporaryTrigger;
  10. public static ManualResetEvent m_eventQuitTemporary;
  11. private static string m_triggerParam;
  12. public static void TemporaryConnThreadTrigger(String param)
  13. {
  14. m_triggerParam = param;
  15. m_eventTemporaryTrigger.Set();
  16. }
  17. static void Main(string[] args)
  18. {
  19. m_eventTemporaryTrigger =new ManualResetEvent(true);
  20. m_eventQuitTemporary = new ManualResetEvent(true);
  21. //m_eventQuitTemporary = new ManualResetEvent(false);
  22. m_eventTemporaryTrigger.Reset(); //临时线程处于工作之中时,m_eventTemporaryTrigger始终处于被触发状态
  23. //  Trigger.strmain();
  24. WaitHandle[] events = new WaitHandle[2];
  25. events[0] = m_eventQuitTemporary;
  26. events[1] = m_eventTemporaryTrigger;
  27. //等待退出信号事件或触发事件
  28. // 返回结果:
  29. //     满足等待的对象的数组索引。
  30. int index = WaitHandle.WaitAny(events);
  31. Console.WriteLine("run no wait");
  32. if (index == 0)
  33. {//如果是将Main(),第三行置为false则不执行下面语句
  34. Console.WriteLine("m_eventQuitTemporary run");
  35. Console.WriteLine(m_triggerParam);
  36. }
  37. }
  38. }
  39. public class Trigger
  40. {
  41. public static void strmain()
  42. {
  43. Program.TemporaryConnThreadTrigger("m_eventQuitTemporary run show");
  44. }
  45. }
  46. }

要注意的是ManualResetEvent和AutoResetEvent 的构造函数都有一个bool的参数,用这个参数可以指定初始情况下,同步对象的处于阻塞(设置为false)还是非阻塞(设置为true)的状态。 
另外WaitOne方法也可以带两个参数: 
WaitOne (int millisecondsTimeout,bool exitContext) 
millisecondsTimeout:等待的毫秒数,或为 Timeout.Infinite (-1),表示无限期等待。 
exitContext:为 true,则等待之前先退出上下文的同步域(如果在同步上下文中),然后在稍后重新获取它;否则为false。 
就是说,等待是可以加上一个期限的,如果等待的同步对象一直都不Set()的话,那么程序就会卡死,所以在WaitOne方法里面可以放置一个时间期限,单位是毫秒。

线程 ManualResetEvent 类的更多相关文章

  1. FreeOnTerminate 的线程在线程管理类的Destroy释放时手工释放的问题

    这个问题折腾了我整整一天. 有一个线程管理类,集中管理所有新建的线程, 线程统一在创建时标识 FreeOnTerminate 为 True. 因为有的线程是不限次循环的,所以在管理类最后 Destro ...

  2. Qt 学习之路 :Qt 线程相关类

    希望上一章有关事件循环的内容还没有把你绕晕.本章将重新回到有关线程的相关内容上面来.在前面的章节我们了解了有关QThread类的简单使用.不过,Qt 提供的有关线程的类可不那么简单,否则的话我们也没必 ...

  3. C#中假设正确使用线程Task类和Thread类

    C#中使用线程Task类和Thread类小结 刚接触C#3个月左右.原先一直使用C++开发.由于公司的须要,所地採用C#开发.主要是控制设备的实时性操作,此为背景. 对于C#中的Task和Thread ...

  4. 工作线程基类TaskSvc

    工作线程基类TaskSvc 前端时间用ACE写代码,发ACE_Task确实好用.不但能提供数量一定的线程,还能够让这些继承的线程函数自由访问子类的private和protected变量.此外,ACE_ ...

  5. Java多线程之线程其他类

    Java多线程之线程其他类 实际编码中除了前面讲到的常用的类之外,还有几个其他类也有可能用得到,这里来统一整理一下: 1,Callable接口和Future接口 JDK1.5以后提供了上面这2个接口, ...

  6. 『TensorFlow』线程控制器类&变量作用域

    线程控制器类 线程控制器原理: 监视tensorflow所有后台线程,有异常出现(主要是越界,资源循环完了)时,其should_stop方法就会返回True,而它的request_stop方法则用于要 ...

  7. linux通过c++实现线程池类

    目录 线程池的实现 线程池已基于C++11重写 : 基于C++11实现线程池的工作原理 前言 线程池的概念 使用原因及适用场合 线程池的实现原理 程序测试 线程池的实现 线程池已基于C++11重写 : ...

  8. java并发编程:线程安全管理类--原子包--java.util.concurrent.atomic

    java.util.concurrent.atomic 的描述 AtomicBoolean 可以用原子方式更新的 boolean 值. AtomicInteger 可以用原子方式更新的 int 值. ...

  9. JUC——ThreadFactory线程工厂类(四)

    ThreadFactory线程工厂类 在默认情况下如果要想创建一个线程类对象,大部分情况的选择是:直接通过子类为父类进行实例化,利用Runnable子类为Runnable接口实例化. 或者直接调用La ...

随机推荐

  1. [Cracking the Coding Interview] 4.3 List of Depths

    Given a binary tree, design an algorithm which creates a linked list of all the nodes at each depth. ...

  2. python2.7入门---列表(List)

        序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推.Python有6个序列的内置类型,但最常见的是列表和元组. ...

  3. responsive grid

    http://csswizardry.com/csswizardry-grids/ http://unsemantic.com/demo-responsive http://getbootstrap. ...

  4. 面试-MySQL总结

    三范式 三范式定义(范式和反范式) 1NF:每个数据项都是最小单元,不可分割,确定行列之后只能对应一个数据. 2NF:每一个非主属性完全依赖于候选码(属性组的值能唯一的标识一个元组,但是其子集不可以) ...

  5. 【转】Git远程操作详解

    Git是目前最流行的版本管理系统,学会Git几乎成了开发者的必备技能. Git有很多优势,其中之一就是远程操作非常简便.本文详细介绍5个Git命令,它们的概念和用法,理解了这些内容,你就会完全掌握Gi ...

  6. 在编程的时候,NotePad++ 中闪烁的光标突然有竖着闪烁的编程蓝色下划线闪烁的--小技巧告诉你-费元星

    当在写代码时出现的光标闪烁(横线闪烁) 在键盘上找 Insert ,按这个Insert就可以把横向闪烁光标( _ )修改成竖向闪烁光标样式( | ),横向光标会在你写代码的时候修改前面的代码,把光标移 ...

  7. Objective-C反射机制

    oc反射机制有三个用途: 1.获得Class Class LoginViewController = NSClassFromString(@"LoginViewController" ...

  8. Linux系统学习笔记(1)

    学习地址:http://www.runoob.com/linux/linux-tutorial.html 1.学习Windows和Linux哪个比较难? 前期是Windows容易学习,后期是Linux ...

  9. bug单的提交

    顶头信息 所属产品,所属项目,所属模块,影响版本,当前指派,bug类型:代码错误,界面优化,设计缺陷,性能问题,标准规范,其他,安全相关.bug标题,严重程度,优先级 缺陷描述 bug描述,预置条件, ...

  10. 第十六篇 Python之迭代器与生成器

    一.迭代器 一. 递归和迭代 生活实例说明什么是递归和迭代 A想去腾达大厦,问B怎么走路,B 说我不知道,我给你问问C,C也不知道,C又去问D,D知道,把路告诉了C,C又告诉B,B最后告诉A, 这就是 ...