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-03 06:48:01

WaitHandle——使用ManualResetEvent的相关文章

c#开源消息队列中间件EQueue 教程

一.简介 EQueue是一个参照RocketMQ实现的开源消息队列中间件,兼容Mono,具体可以参看作者的文章<分享一个c#写的开源分布式消息队列equeue>.项目开源地址:https://github.com/tangxuehua/equeue,项目中包含了队列的全部源代码以及如何使用的示例. 二.安装EQueue Producer.Consumer.Broker支持分布式部署,安装EQueue需要.NET 4, Visual Studio 2010/2012/2013. 目前EQueue

重新想象 Windows 8 Store Apps (47) - 多线程之线程同步: Semaphore, CountdownEvent, Barrier, ManualResetEvent, AutoResetEvent

原文:重新想象 Windows 8 Store Apps (47) - 多线程之线程同步: Semaphore, CountdownEvent, Barrier, ManualResetEvent, AutoResetEvent [源码下载] 重新想象 Windows 8 Store Apps (47) - 多线程之线程同步: Semaphore, CountdownEvent, Barrier, ManualResetEvent, AutoResetEvent 作者:webabcd 介绍重新想

ASP.NET教程:WaitHandle类

当程序运行时,碰到了一个问 题,如果WaitHandle数组超过64个元素之后,WaitHandle对象的WatiAll方法罢工了.后来为了程序能运行,只得想了一个笨办法: 先创建两个WaitHandle对象放在数组,然后用循环两个两个地运行任务. 最近笔者在用.Net写程序时遇到一个问题:有N个互不相关的任务要在线程池中跑,但有一个线程要等待N个任务完成之后才能继续.而这个N是个未知数,可能会 很大(因此才会想到使用线程池而不是手动去new一个therad).翻了翻.Net类库的文档,发现一个

多线程中的ManualResetEvent

先来看一下简单的多线程控制台程序: using System;using System.Threading; namespace ManualResetEventStudy{     class ThreadClass    {        static void t1()        {            for (int x = 1; x <= 5; x++)            {                Thread.Sleep(500);                

线程-关于WaitHandle的WaitAny

问题描述 关于WaitHandle的WaitAny MSDN上的示例代码https://msdn.microsoft.com/zh-cn/library/system.threading.waithandle(v=vs.110).aspx --//前面的代码省略了 Console.WriteLine("The main thread is waiting for either task to complete."); ThreadPool.QueueUserWorkItem(new W

AutoResetEvent和ManualResetEvent

转自 http://www.cnblogs.com/vcool/archive/2008/05/13/1195213.html 在.Net多线程编程中,AutoResetEvent和ManualResetEvent这两个类经常用到, 他们的用法很类似,但也有区别. Set方法将信号置为发送状态,Reset方法将信号置为不发送状态,WaitOne等待信号的发送. 可以通过构造函数的参数值来决定其初始状态,若为true则非阻塞状态,为false为阻塞状态. 如果某个线程调用WaitOne方法,则当信

asp.net中ManualResetEvent类使用方法

ManualResetEvent详解 ManualResetEvent 允许线程通过发信号互相通信.通常,此通信涉及一个线程在其他线程进行之前必须完成的任务.当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用 Reset 以将 ManualResetEvent 置于非终止状态,此线程可被视为控制 ManualResetEvent.调用 ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号.当控制线程完成活动时,它调用 Set 以发出等待线程可以继续

WaitHandle——使用Semaphore

    semaphore也继承自waithandle,它用于锁机制,与Mutex不同的是,它允许指定数量的线程同时访问资源,在线程超过数量以后,则进行排队等待,直到之前的线程退出.     Semaphore很适合应用于web服务器这样的高并发场景,可以限制对资源访问的线程数.     Monitor与monitor都有一个锁持有者,而semaphore则不需要,因此通常将sempahore声明为静态的.      来看下面的示例: namespace 使用Semaphore { class

WaitHandle——使用Mutex

替代object加锁方式    使用System.object对象作为线程同步的工具,建立了一个基本的锁机制,确保资源只能同时被一个线程所访问.      但是这个对象不作任何其他用途,知识用于锁机制.    如果有一个类型可以专注于为线程同步的锁机制和信号量机制提供服务,那么上面的代码就可以简化.    .net中提供了更强大的system.threading.waithandle及其子类型,可以实现类似的效果.      首先来看Mutex是如何取代object的: //System.Thr