原文链接 http://dotnetpattern.com/threading-manualresetevent

ManualResetEvent 和AutoResetEvent一样,是另外一种.NET线程同步技术。

ManualResetEvent被用于在两个或多个线程间进行线程信号发送。

多个线程可以通过调用ManualResetEvent对象的WaitOne方法进入等待或阻塞状态。当控制线程调用Set()方法,所有等待线程将恢复并继续执行。

ManualResetEvent是如何工作的

在内存中保持着一个bool值,如果bool值为False,则使所有线程阻塞,反之,如果bool值为True,则使所有线程退出阻塞。当我们创建ManualResetEvent对象的实例时,我们在函数构造中传递默认的bool值,以下是实例化ManualResetEvent的例子。

ManualResetEvent manualResetEvent = new ManualResetEvent(false);

在上面代码中,我们初始化了一个值为False的ManualResetEvent对象,这意味着所有调用WaitOne放的线程将被阻塞,直到有线程调用了 Set() 方法。而如果我们用值True来对ManualResetEvent对象进行初始化,所有调用WaitOne方法的线程并不会被阻塞,可以进行后续的执行。

WaitOne方法

该方法阻塞当前线程并等待其他线程发送信号。如果收到信号,它将返回True,反之返回False。以下演示了如何调用该方法。

manualResetEvent.WaitOne();

在WaitOne方法的第二个重载版本中,我们可以指定当前线程等待信号的时间间隔。如果在时间间隔内,没有收到信号,方法将返回False并继续执行。以下代码演示了带时间间隔参数的WaitOne调用。

bool isSignalled = manualResetEvent.WaitOne(TimeSpan.FromSeconds(5));

我们指定了5秒作为WaitOne方法的参数,如果manualResetEvent对象在5秒内收到信号,它将isSignalled赋值为False。

Set方法

该方法用于给所有等待线程发送信号。 Set() 方法的调用使得ManualResetEvent对象的bool变量值为True,所有线程被释放并继续执行。下面是调用的例子:

manualResetEvent.Set();

Reset方法
   一旦我们调用了ManualResetEvent对象的Set()方法,它的bool值就变为true,我们可以调用Reset()方法来重置该值,Reset()方法重置该值为False。以下是调用Reset方法的例子:

manualResetEvent.Reset();

如果我们想多次发送信号,那么我们必须在调用Set()方法后立即调用Reset()方法。

ManualResetEvent 例子
    下面的例子展示了如何使用ManualResetEvent来释放多个线程。我们用false值实例化了ManualResetEvent对象,它将阻塞所有调用WaitOne方法的线程。我们创建了两个线程,它们调用方法GetDataFromServer,并以server数量作为参数。
      在调用WaitOne方法获取第一批数量后,两个线程均等待来自调用WaitOne线程的信号。当控制线程调用manualrestEvent对象的Set方法,两个线程均被释放并继续运行。在调用Set方法后,我们立即调用了Reset方法,这将改变manualrestEvent对象的bool值为false。所以,如果线程再次调用WaitOne方法,他们仍然会被阻塞。
    在从服务器获取第二批数据后,两个线程均调用了WaitOne方法。在2秒后,控制线程再次调用Set方法释放两个线程。

class Program
{static ManualResetEvent manualResetEvent = new ManualResetEvent(false);static void Main(string[] args){Task task = Task.Factory.StartNew(() =>{GetDataFromServer(1);});Task.Factory.StartNew(() =>{GetDataFromServer(2);});//Send first signal to get first set of data from server 1 and server 2
        manualResetEvent.Set();manualResetEvent.Reset();Thread.Sleep(TimeSpan.FromSeconds(2));//Send second signal to get second set of data from server 1 and server 2
        manualResetEvent.Set();Console.ReadLine();/* Result* I get first data from server1* I get first data from server2* I get second data from server1* I get second data from server2* All the data collected from server2* All the data collected from server1*/}static void GetDataFromServer(int serverNumber){//Calling any webservice to get dataConsole.WriteLine("I get first data from server" + serverNumber);manualResetEvent.WaitOne();Thread.Sleep(TimeSpan.FromSeconds(2));Console.WriteLine("I get second data from server" + serverNumber);manualResetEvent.WaitOne();Console.WriteLine("All the data collected from server" + serverNumber);}
}

转载于:https://www.cnblogs.com/czytcn/p/8085378.html

C# ManualResetEvent相关推荐

  1. C# “Thread类Suspend()与Resume()已过时” 解决方法(利用ManualResetEvent类)

    C# "Thread类Suspend()与Resume()已过时" 解决方法(利用ManualResetEvent类) 参考文章: (1)C# "Thread类Suspe ...

  2. AutoResetEvent和ManualResetEvent

    首先说说线程的终止状态和非终止状态.AutoResetEvent和ManualResetEvent的构造函数中,都有bool变量来指明线程的终止状态和非终止状态.true表示终止状态,false表示非 ...

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

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

  4. 线程池 ManualResetEvent

    线程池: "线程池"是可以用来在后台执行多个任务的线程集合.(有关背景信息,请参见使用线程处理.)这使主线程可以自由地异步执行其他任务. 线程池通常用于服务器应用程序.每个传入请求 ...

  5. 多线程中的ManualResetEvent

    先来看一下简单的多线程控制台程序: using System; using System.Threading; namespace ManualResetEventStudy { class Thre ...

  6. 【深度好文】多线程之WaitHandle--派生EventWaitHandle事件构造-》AutoResetEvent、ManualResetEvent...

    AutoResetEvent/ManualResetEvent 都是继承自 EventWaitHandle ,EventWaitHandle继承自WaitHandle. 在讨论这个问题之前,我们先了解 ...

  7. 关于AutoResetEvent 和ManualResetEvent

    在公司的代码里面看到这两个类的使用了,第一次去msdn上的时候,看的一头雾水(关键是没有找对方法) http://www.cnblogs.com/qingyun163/archive/2013/01/ ...

  8. C# ManualResetEvent的理解和用法

    ManualResetEvent是C#中一个比较常用的工具,可用于线程间通信,实现一种类似信号量的功能(不知道我这样描述是否恰当,有可能不是"类似",而"就是" ...

  9. autoresetevent java_[原创]AutoResetEvent, ManualResetEvent的Java模拟

    AutoResetEvent, ManualResetEvent是C#中常用的线程同步方法,在Java中可以模拟,AutoResetEvent使用Semaphore,增加的是许可证数量,程序里只有一个 ...

最新文章

  1. chrono 使用备注
  2. [2010山东ACM省赛] Greatest Number(数的组合+二分搜索)
  3. 利用正则表达式去除所有html标签,只保留文字
  4. python手机版怎么运行项目或脚本-python脚本运行的几种方式
  5. python3.7安装turtle步骤-Python3安装turtle问题
  6. PyTorch入门-词向量
  7. (67)FPGA面试题-为priority encoder编写Verilog代码,实现MUX4_1
  8. python Pipe
  9. [LeetCode] 204. Count Primes
  10. 购物车=收藏夹?一文理解淘宝购物车背后的逻辑
  11. SEO内容构建流程,SEO内容建设策略有哪些?
  12. Python数据分析实例
  13. cs透视源码c语言,CS--GO透视自瞄C++源码 CSGO C++源代码 参考学习!!!(CSGO C++ source code) - 下载 - 搜珍网...
  14. ASO关键词优化如何提升APP榜单排名,aso 关键词优化工具
  15. 计算机程序设计c++ 5-1:函数的调用格式
  16. 自己动手开发网络服务器(一)
  17. 用 python 来操作 docx(使用 docx 库操作 docx 格式文件)
  18. sql命令手册(转载)http://www.fanqiang.com
  19. 软件项目的规模、工作量和成本是如何进行估算的
  20. windows应用(vc++2022)MFC基础到实战(1)-基础(1)

热门文章

  1. webpack基础+webpack配置文件常用配置项介绍+webpack-dev-server
  2. Weblogic部署项目过程中的一些问题
  3. 最长上升子序列(LIS)
  4. 数据库开发基本操作-数据库基础知识
  5. 文件中的类都不能进行设计,因此未能为该文件显示设计器。设计器检查出文件中有以下类: FormMain --- 未能加载基类...
  6. Python基础-----while循环语句
  7. manjaro安装teamviewer实现远程连接
  8. [Android] TableLayout
  9. 设计模式6——创建型模式之原型模式
  10. struts2 18拦截器详解(五)