WaitHandle——使用ManualResetEvent

信号量机制

使用ManualResetEvent和AutoResetEvent都继承自EventWaitHandle(继承自waitHandle)。EventWaitHandle对象有两个状态:收到信号(signaled)和未收到信号(nonsignaled);EventWaitHandle中的set和reset方法分别用于将eventwaitHandle对象的状态设为收到信号和未收到信号。

当EventWaitHandle未收到信号时,任何线程调用基类的wait方法都会被阻塞,知道eventhandle对象的状态变为收到信号。

ManualResetEvent的构造函数接受一个布尔类型,用于设置ManualResetEvent对象的初是状态为收到信号还是未收到信号。对象状态确定之后,将会一直保持下去,直到有线程调用set或者reset方法。

示例:

namespace 使用ManualResetEvent
{
    class Program
    {

        //当创建ManualResetEvent对象时,构造函数的参数为true,表示已经收到信号。
        //因此当worker线程在threadentry方法中调用waitone时不会被阻塞,而是立即执行后面的语句。

        ManualResetEvent mre = new ManualResetEvent(true);//signaled :收到信号状态
        //如果把构造函数的参数改为false:
            //worker线程将会被阻塞在waitone的位置无法执行,因为它在等待ManualResetEvent对象的状态
            //变为已收到的信号。

        //从这里可以看出,waitone方法在这里和mutex中的用法完全不同,这里是用于信号机制,而mutex中是用于锁机制

        static void Main(string[] args)
        {
            Thread.CurrentThread.Name = "main ";
            Program p = new Program();
            Thread worker = new Thread(p.ThreadEntry);
            worker.Name = "worker";
            worker.Start();
            Console.WriteLine("main: finished");
        }
        void ThreadEntry() {
            int i = 0;
            string name = Thread.CurrentThread.Name;
            while (i<10)
            {
                mre.WaitOne();
                Console.WriteLine("{0}:{1}---{2}",name ,i,DateTime .Now.Millisecond);
                i++;
            }

        }

    }
}

使用set和reset方法

示例:

namespace ManualResetEvent的set方法和reset方法
{
    class Program
    {

        ManualResetEvent mre = new ManualResetEvent(false);//未收到信号量

        static void Main(string[] args)
        {
            Thread.CurrentThread.Name = "main ";
            Program p = new Program();
            Thread worker = new Thread(p.ThreadEntry );
            worker.Name = "worker";
            worker.Start();

            p.mre.Set();  //设置为收到信号量
            Console.WriteLine("main:start worker.");
            Thread.Sleep(30);
            p.mre.Reset();  //设置为未收到信号量
            Console.WriteLine("main:stop worker");
            p.mre.Set();   //设置为收到信号量
            Console.WriteLine("main:continue worker");

        }

        void ThreadEntry() {

            int i = 0;
            string name = Thread.CurrentThread.Name;
            while (i<10)
            {
                mre.WaitOne();
                Console.WriteLine("{0}:{1}--{2}",name,i,DateTime .Now.Millisecond);
                Thread.Sleep(10);  //设置sleep,否则循环很快结束,无法实现测试
                i++;

            }
        }
    }
}

这里通过使用set和reset通过设置信号量状态来控制线程。

时间: 2024-08-28 20:45:35

WaitHandle——使用ManualResetEvent的相关文章

AutoResetEvent和ManualResetEvent理解

AutoResetEvent和ManualResetEvent用于多线程之间代码执行顺序的控制,它们继承自WaitHandleAPI类似,使用中还是有区别的. 之前每次需要使用的时候,都去找他们之间的区别.虽然当时是明白了,但没有深入理解透彻,过几天又忘记了.等到下次需要使用的时候又要重新去理解这2个类. 今天再次遇到他们,写下这篇随笔..加深理解印象.到了下次再用到不用再去纠结区别了. 1.构造函数参数 var manualResetEventWaitHandle = new ManualRe

C# 多线程处理相关说明: WaitHandle,waitCallback, ThreadPool.QueueUserWorkItem

class TestThread { static void Main() { //使用WaitHandle静态方法阻止一个线程,直到一个或多个同步对象接收到信号 WaitHandle[] waitHandles = new WaitHandle[] { new ManualResetEvent(false), new ManualResetEvent(false) }; WaitCallback waitCallback = new WaitCallback(MyThreadWork); Wa

AutoResetEvent和ManualResetEvent理解 z

AutoResetEvent和ManualResetEvent用于多线程之间代码执行顺序的控制,它们继承自WaitHandle,API相同,但在使用中还是有区别的. 每次使用时虽然理解了,但由于没有去深入思考记忆,过几天又忘记了.到下次需要使用的时候又要重新去理解这2个类. 今天再次遇到他们,写下这篇随笔..加深理解印象.以后不用去纠结他们了. 1.构造函数参数 var manualResetEventWaitHandle = new ManualResetEvent(true); var au

C# 异步编程1 APM模式异步程序开发

C#已有10多年历史,单从微软2年一版的更新进度来看活力异常旺盛,C#中的异步编程也经历了多个版本的演化,从今天起着手写一个系列博文,记录一下C#中的异步编程的发展历程.广告一下:喜欢我文章的朋友,请点下面的“关注我”.谢谢 我是2004年接触并使用C#的,那时C#版本为1.1,所以我们就从就那个时候谈起.那时后在大学里自己看书写程序,所写的程序大都是同步程序,最多启动个线程........其实在C#1.1的时代已有完整的异步编程解决方案,那就是APM(异步编程模型).如果还有不了解“同步程序.

使用多线程异步创建一组文件

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.IO; using System.Diagnostics; namespace ThreadAppDemo { //mock data class Friend { public string name { get; set; } public stri

浅谈线程池(下):相关试验及注意事项

三个月,整整三个月了,我忽然发现我还有三个月前的一个小系列的文章没有结束,我还欠一个试验!线程池是.NET中的重要组件,几乎所有的异步功能依赖于线程池.之前我们讨论了线程池的作用.独立线程池的存在意义,以及对CLR线程池和IO线程池进行了一定说明.不过这些说明可能有些"抽象",于是我们还是要通过试验来"验证"这些说明.此外,我认为针对某个"猜想"来设计一些试验进行验证是非常重要的能力,如果您这方面的能力略有不足的话,还是尽量加以锻炼并提高吧. C

多线程中的锁系统(三)-WaitHandle、AutoResetEvent、ManualResetEvent

介绍 本章主要说下基于内核模式构造的线程同步方式,事件,信号量. 目录 一:理论 二:WaitHandle 三:AutoResetEvent 四:ManualResetEvent 五:总结 一:理论 我们晓得线程同步可分为,用户模式构造和内核模式构造. 内核模式构造:是由windows系统本身使用,内核对象进行调度协助的.内核对象是系统地址空间中的一个内存块,由系统创建维护. 内核对象为内核所拥有,而不为进程所拥有,所以不同进程可以访问同一个内核对象, 如进程,线程,作业,事件,文件,信号量,互

ManualResetEvent使用

1.定义 MSDN定义: 通知一个或多个正在等待的线程已发生事件.此类不能被继承. 详细说明: ManualResetEvent 允许线程通过发信号互相通信.通常,此通信涉及一个线程在其他线程进行之前必须完成的任务.当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用 Reset 以将 ManualResetEvent 置于非终止状态,此线程可被视为控制 ManualResetEvent.调用 ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号.当

C#各种同步方法 lock, Monitor,Mutex, Semaphore, Interlocked, ReaderWriterLock,AutoResetEvent, ManualResetEvent

看下组织结构: System.Object System.MarshalByRefObject System.Threading.WaitHandle System.Threading.Mutex System.Threading.Semaphore System.Threading.EventWaitHandle System.Threading.ManualResetEvent System.Threading.AutoResetEvent System.Object System.Thre