[C#]『CountdownEvent』任务并行库使用小计
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』任务并行库使用小计的更多相关文章
- [C#]『PLINQ』任务并行库使用小计
并行 LINQ (PLINQ) 是 LINQ to Objects 的并行实现. PLINQ 实现完整的 LINQ 标准查询运算符集作为 T:System.Linq 命名空间的扩展方法,并具有用于并行 ...
- [C#]『Barrier』任务并行库使用小计
Barrier 是一个对象,它可以在并行操作中的所有任务都达到相应的关卡之前,阻止各个任务继续执行. 如果并行操作是分阶段执行的,并且每一阶段要求各任务之间进行同步,则可以使用该对象. --MSDN ...
- [C#]『Task』任务并行库使用小计
1.简单创建使用 using System; using System.Diagnostics; using System.Threading; using System.Threading.Task ...
- C# 任务并行库使用小计 z
1.简单创建使用 using System; using System.Diagnostics; using System.Threading; using System.Threading.Task ...
- 『计算机视觉』imgaug图像增强库中部分API简介
https://github.com/aleju/imgaug 介绍一下官方demo中用到的几个变换,工程README.md已经给出了API简介,个人觉得不好理解,特此单独记录一下: import n ...
- 『TensorFlow』分布式训练_其二_单机多GPU并行&GPU模式设定
建议比对『MXNet』第七弹_多GPU并行程序设计 一.tensorflow GPU设置 GPU指定占用 gpu_options = tf.GPUOptions(per_process_gpu_mem ...
- 『开源』Slithice 2013 服务器集群 设计和源码
相关介绍文章: <『设计』Slithice 分布式架构设计-支持一体式开发,分布式发布> <『集群』001 Slithice 服务器集群 概述> <『集群』002 Sli ...
- 『计算机视觉』Mask-RCNN_推断网络其四:FPN和ROIAlign的耦合
一.模块概述 上节的最后,我们进行了如下操作获取了有限的proposal, # [IMAGES_PER_GPU, num_rois, (y1, x1, y2, x2)] # IMAGES_PER_GP ...
- 『计算机视觉』Mask-RCNN
一.Mask-RCNN流程 Mask R-CNN是一个实例分割(Instance segmentation)算法,通过增加不同的分支,可以完成目标分类.目标检测.语义分割.实例分割.人体姿势识别等多种 ...
随机推荐
- Git简介:
Git中文文档 1.详解在Visual Studio中使用git版本系统(图文) 2.GitExtensions下载地址:http://gitextensions.codeplex.com/ 3.Gi ...
- IOS GCD 使用(三)单例模式
一 Dispatch_once函数简介 使用dispatch_once提价的代码块,即便你提交多次,只能执行一次. void dispatch_once(dispatch_once_ ...
- ARR状态监控脚本
##################################################################################### # THIS IS SAMP ...
- [学习笔记]--Jfinal 表单提交附件
近期.项目里面用到了Jfinal 里面的上传附件. Jfinal 的Controller 里面提供了一个 getFile系列方法提供文件上传. 我这里呢,是文件上传和表单參数一起提交. 页面类似下图: ...
- Linux vmstat具体解释(系统IO)
1. vmstat 能够展现给定时间间隔的server的状态值,包含server的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况 vmstat 2 10 2: 每隔2s 10 : 统计10次 ...
- ORACLE ------MYSQL2014 大会 PPT
https://oracleus.activeevents.com/2014/connect/focusOnDoc.do?focusID=17888
- QT线程(二)---线程同步
线程互斥 多线程运行时,通常会访问同一个变量,同一个数据结构,或者同一段代码.因此,需要使用互斥技术来保护上述资源,确保多线程执行的正确性. 注: 我们通常说某个函数是线程安全的,也就是因为该函数 ...
- javabean对象要实现的接口们和要重写的方法们
在使用list集合的时候,什么也不用. 原因:list允许存储重复的元素. 在使用set集合的时候,要重写,equals()方法 和 hashCode() 方法. 愿意:set集合 不允许存放相同的元 ...
- Hibernate关联映射1:一对一主键关联
2张表之间通过主键形成一对一映射关系,如一个人只能有一张身份证: t_identity_card表建表语句: CREATE TABLE `t_identity_card` ( `id` int(11) ...
- Java中的编码问题
下面将侧重介绍java乱码是如何产生的.存在哪些乱码的情况.该如何从根本上解决乱码问题.各位随博主一起征服令人厌烦的java乱码问题吧!!! 一.Java编码转换过程 我们总是用一个java类文件和用 ...