System.Threading.CountdownEvent  是一个同步基元,它在收到一定次数的信号之后,将会解除对其等待线程的锁定。 CountdownEvent  专门用于以下情况:您必须使用 ManualResetEvent 或 ManualResetEventSlim,并且必须在用信号通知事件之前手动递减一个变量。 例如,在分叉/联接方案中,您可以只创建一个信号计数为 5 的 CountdownEvent,然后在线程池上启动五个工作项,并且让每个工作项在完成时调用 Signal。 每次调用 Signal 时,信号计数都会递减 1。 在主线程上,对 Wait 的调用将会阻塞,直至信号计数为零。
CountdownEvent  具有这些附加功能:
•可通过使用取消标记来取消等待操作。
•创建实例之后可以递增它的信号计数。
•通过调用 Reset 方法,可在 Wait 返回之后重用实例。
•实例公开 WaitHandle 以便与其他 .NET Framework 同步 API(例如 WaitAll)进行集成。——MSDN

1.普通示例

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication18
{
    class Program
    {

        static CountdownEvent cde = null;
        /// <summary>
        /// 模拟建房子
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            //建房子第一期工人
            string[] _bhPerson1 = new string[5] { "Yan", "Zhi", "wei", "Do", "Work" };
            //建房子第二期工人
            string[] _bhPerson2 = new string[3] { "Yan2", "Zhi2", "wei2" };
            //建房子第三期工人
            string[] _bhPerson3 = new string[3] { "Yan3", "Zhi3", "wei3" };

            using (cde = new CountdownEvent(Environment.ProcessorCount))//开始监管,相当于监工
            {
                cde.Reset(_bhPerson1.Length);//设置第一期建造需要5个人
                foreach (string person in _bhPerson1)
                {
                    Task.Factory.StartNew(() =>
                    {
                        BuilderHourseStep1(person);
                    });

                }
                cde.Wait();//等待第一期建造完成
                Console.WriteLine("-----------------------");

                cde.Reset(_bhPerson2.Length);//设置第二期建需要三个人
                foreach (string person in _bhPerson2)
                {
                    Task.Factory.StartNew(() =>
                      {
                          BuilderHourseStep2(person);
                      });
                }
                cde.Wait();//等待第二期建造完成
                Console.WriteLine("-----------------------");

                cde.Reset(_bhPerson3.Length);//设置第三期建需要三个人
                foreach (string person in _bhPerson3)
                {
                    Task.Factory.StartNew(() =>
                        {
                            BuilderHourseStep3(person);
                        });
                }
                cde.Wait();//等待第三期建造完成
                Console.WriteLine("-----------------------");
            }
        }

        /// <summary>
        /// 建房子第一道所需要的工序
        /// </summary>
        /// <param name="person"></param>
        static void BuilderHourseStep1(string person)
        {
            try
            {
                Console.WriteLine(string.Format("『{0}』BuilderHourseStep1....", person));
            }
            finally
            {
                cde.Signal();//建造完成一点后,通知监工
            }
        }
        /// <summary>
        /// 建房子第二道所需要的工序
        /// </summary>
        /// <param name="person"></param>
        static void BuilderHourseStep2(string person)
        {
            try
            {
                Console.WriteLine(string.Format("『{0}』BuilderHourseStep2.....", person));
            }
            finally
            {
                cde.Signal();
            }
        }
        /// <summary>
        /// 建房子第三道所需要的工序
        /// </summary>
        /// <param name="person"></param>
        static void BuilderHourseStep3(string person)
        {
            try
            {
                Console.WriteLine(string.Format("『{0}』BuilderHourseStep3.......", person));
            }
            finally
            {
                cde.Signal();
            }
        }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

代码效果

 

2.超时演示,延续上面例子,建造房子存在延期的情况,譬如某个工作工作懒散,那么需要给整个一期建造设置一个总的时限。

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication18
{
    class Program
    {
        static CountdownEvent cde = null;
        static int overLimitTime = 5000;//第一期工作完成时间
        /// <summary>
        /// 模拟建房子
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            try
            {
                //建房子第一期工人
                string[] _bhPerson1 = new string[5] { "Yan", "Zhi", "wei", "Do", "Work" };
                //建房子第二期工人
                string[] _bhPerson2 = new string[3] { "Yan2", "Zhi2", "wei2" };
                //建房子第三期工人
                string[] _bhPerson3 = new string[3] { "Yan3", "Zhi3", "wei3" };

                using (cde = new CountdownEvent(Environment.ProcessorCount))//开始监管,相当于监工
                {
                    cde.Reset(_bhPerson1.Length);//设置第一期建造需要5个人
                    Random _workTime = new Random();
                    foreach (string person in _bhPerson1)
                    {
                        Task.Factory.StartNew(() =>
                        {
                            int _doWorkTime = _workTime.Next(3000, 6000);//工人工作时间
                            BuilderHourseStep1(person, _doWorkTime);
                        });

                    }
                    bool _bdStep1Result = cde.Wait(overLimitTime);
                    Console.WriteLine(string.Format("第一期建造状态:{0}.", _bdStep1Result == true ? "完成" : "延时"));//等待第一期建造完成 限制5秒内完成

                    Console.WriteLine("-----------------------");
                    if (!_bdStep1Result) return;
                    cde.Reset(_bhPerson2.Length);//设置第二期建需要三个人
                    foreach (string person in _bhPerson2)
                    {
                        Task.Factory.StartNew(() =>
                          {
                              BuilderHourseStep2(person);
                          });
                    }
                    cde.Wait();//等待第二期建造完成
                    Console.WriteLine("-----------------------");

                    cde.Reset(_bhPerson3.Length);//设置第三期建需要三个人
                    foreach (string person in _bhPerson3)
                    {
                        Task.Factory.StartNew(() =>
                            {
                                BuilderHourseStep3(person);
                            });
                    }
                    cde.Wait();//等待第三期建造完成
                    Console.WriteLine("-----------------------");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("Excepton Message: {0}", ex.Message.Trim()));
            }
            finally
            {
                Console.ReadLine();
            }
        }

        /// <summary>
        /// 建房子第一道所需要的工序
        /// </summary>
        /// <param name="person"></param>
        static void BuilderHourseStep1(string person, int doWorkTime)
        {
            bool _isDoWork = doWorkTime < overLimitTime;
            try
            {
                if (_isDoWork)
                    Console.WriteLine(string.Format("『{0}』做事情花费了,{1}s........", person, doWorkTime));
                else
                    Console.WriteLine(string.Format("『{0}』做事情太墨迹,花费了{1}s....", person, doWorkTime));
                Thread.Sleep(doWorkTime);
            }
            finally
            {
                if (_isDoWork)
                    cde.Signal();//建造完成后,通知监工
            }
        }
        /// <summary>
        /// 建房子第二道所需要的工序
        /// </summary>
        /// <param name="person"></param>
        static void BuilderHourseStep2(string person)
        {
            try
            {
                Console.WriteLine(string.Format("『{0}』BuilderHourseStep2.....", person));
            }
            finally
            {
                cde.Signal();
            }
        }
        /// <summary>
        /// 建房子第三道所需要的工序
        /// </summary>
        /// <param name="person"></param>
        static void BuilderHourseStep3(string person)
        {
            try
            {
                Console.WriteLine(string.Format("『{0}』BuilderHourseStep3.......", person));
            }
            finally
            {
                cde.Signal();
            }
        }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

代码效果

[C#]『CountdownEvent』任务并行库使用小计的更多相关文章

  1. [C#]『PLINQ』任务并行库使用小计

    并行 LINQ (PLINQ) 是 LINQ to Objects 的并行实现. PLINQ 实现完整的 LINQ 标准查询运算符集作为 T:System.Linq 命名空间的扩展方法,并具有用于并行 ...

  2. [C#]『Barrier』任务并行库使用小计

    Barrier  是一个对象,它可以在并行操作中的所有任务都达到相应的关卡之前,阻止各个任务继续执行. 如果并行操作是分阶段执行的,并且每一阶段要求各任务之间进行同步,则可以使用该对象. --MSDN ...

  3. [C#]『Task』任务并行库使用小计

    1.简单创建使用 using System; using System.Diagnostics; using System.Threading; using System.Threading.Task ...

  4. C# 任务并行库使用小计 z

    1.简单创建使用 using System; using System.Diagnostics; using System.Threading; using System.Threading.Task ...

  5. 『计算机视觉』imgaug图像增强库中部分API简介

    https://github.com/aleju/imgaug 介绍一下官方demo中用到的几个变换,工程README.md已经给出了API简介,个人觉得不好理解,特此单独记录一下: import n ...

  6. 『TensorFlow』分布式训练_其二_单机多GPU并行&GPU模式设定

    建议比对『MXNet』第七弹_多GPU并行程序设计 一.tensorflow GPU设置 GPU指定占用 gpu_options = tf.GPUOptions(per_process_gpu_mem ...

  7. 『开源』Slithice 2013 服务器集群 设计和源码

    相关介绍文章: <『设计』Slithice 分布式架构设计-支持一体式开发,分布式发布> <『集群』001 Slithice 服务器集群 概述> <『集群』002 Sli ...

  8. 『计算机视觉』Mask-RCNN_推断网络其四:FPN和ROIAlign的耦合

    一.模块概述 上节的最后,我们进行了如下操作获取了有限的proposal, # [IMAGES_PER_GPU, num_rois, (y1, x1, y2, x2)] # IMAGES_PER_GP ...

  9. 『计算机视觉』Mask-RCNN

    一.Mask-RCNN流程 Mask R-CNN是一个实例分割(Instance segmentation)算法,通过增加不同的分支,可以完成目标分类.目标检测.语义分割.实例分割.人体姿势识别等多种 ...

随机推荐

  1. 【玩转微信公众平台之六】 搭建新浪SAEserver

    赶紧接上一篇继续讲. ------本篇将介绍怎样搭建 新浪SAEserver.猛戳 http://sae.sina.com.cn/1.先自己注冊一个账号,假设有新浪的账号,微博之类的都能够直接拿来用, ...

  2. Yii CGridView 基本使用(三)关联表相关字段搜索

    加入 关联表 相关字段的搜索: 先说一句,我们在这里仅仅谈 "一对多" 的关联搜索,首先,不要忘了我们的数据库,忘记的同学请戳这里:这里.能够看到在 tbl_post 中是有一个外 ...

  3. (BUG已修改,最优化)安卓ListView异步加载网络图片与缓存软引用图片,线程池,只加载当前屏之说明

    原文:http://blog.csdn.net/java_jh/article/details/20068915 迟点出更新的.这个还有BUG.因为软引应不给力了.2.3之后 前几天的原文有一个线程管 ...

  4. linux中shell变量$#,$@,$0,$1,$2的含义解释

    linux中shell变量$#,$@,$0,$1,$2的含义解释 linux中shell变量$#,$@,$0,$1,$2的含义解释:  变量说明:  $$  Shell本身的PID(ProcessID ...

  5. Awake和Start

    经过查阅资料和自己的理解整理出来的,欢迎大家指教. Awake和Start对比 awake比start先执行. 当有多个类的时候,所有类的awake执行完了才会执行start. awake里面一般放初 ...

  6. phpcms 源码分析一: common.inc.php

      其实就是从网上找到的的逆雪寒的分析, 我下来之后发现格式和错字的问题,非常影响阅读,现在我就是做了下搬运工的角色, 同时将格式调整到可读性提高点而已,让各位看官稍微舒心点: 下面进入整体: < ...

  7. Java基础知识强化之集合框架笔记74:各种集合常见功能 和 遍历方式总结

    1. Collection add() remove() contains() iterator() size() 遍历: 增强for 迭代器 |--List get() 遍历: 普通for |--S ...

  8. 3.linux安装vsftpd服务

    1.首先查看本地是否安装了vsftpd rpm -qa |grep vsftpd 2.安装vsftpd: yum install vsftpd 3.查询当前ftp状态 chkconfig --list ...

  9. 安卓项目-利用Sqlite数据库,开发新闻发布系统

    本教程致力于程序员可以快速的学习安卓移动端手机开发. 适合于已经习得一种编程语言的同仁. 更多志同道合,想要学习更多编程技术的大神们. 小弟不才,麻烦关注一下我的今日头条号-做全栈攻城狮. 本文章是基 ...

  10. 处理 eclipse 导入报错 Invalid project description,问题

    有时候在添加工程时,会出现如图所示的错误信息, ,提示显示将要添加的工程已经存在,但是在工作空间里却找不到,这个时候,要做就是, 在导入的时候选择General->Existing Projec ...