使用Barrier分三步将大象放入冰箱
class Program
{
//构造大象和冰箱
private static ElephantsAndFridges elephantsAndFridges = new ElephantsAndFridges(); static void Main(string[] args)
{
int taskCnt = ; //此处有3个Task来完成工作(注意多任务与多线程及堆栈数据边界)
//并将每个任务的执行结果返回
Task<PhaseTask>[] tasks = new Task<PhaseTask>[taskCnt]; //使多个任务能够采用并行方式依据某种算法在多个阶段中协同工作
// 参数:
// participantCount:
// 参与线程的数量。
//
// postPhaseAction:
// 每个阶段完成之后执行。 可传递 null ,以指示不执行任何操作
Barrier barrier = new Barrier(taskCnt, (b) =>
{
Console.WriteLine(string.Format("第{0}阶段已完成", b.CurrentPhaseNumber + ));
Console.WriteLine();
});
for (int i = ; i < taskCnt; i++)
{
//使用Task工厂启3个任务
tasks[i] = Task<PhaseTask>.Factory.StartNew((obj) =>
{
int cnt = (int)obj; //一个任务一个冰箱(冰箱具有打开和关闭冰箱门及放大象操作)
Fridge fridge = new Fridge(); //注:此处不能用i,存在执行顺序问题
//例如:还未开始从elephantsAndFridges中拿数据,i的值就已经加1了,此时拿的就是i+1位置,而非i位置的数据
fridge.ElephantName = elephantsAndFridges.elephants.ElementAtOrDefault(cnt).ElephantName;
fridge.FridgeName = elephantsAndFridges.fridges.ElementAtOrDefault(cnt).FridgeName; //第一步
fridge.PhaseTaskResult.FirstResult = fridge.OpenTheDoor();
//用信号通知的参与者已达到屏障和所有其他参与者到达屏障也会等待
barrier.SignalAndWait(); //第二步
fridge.PhaseTaskResult.SecondResult = fridge.EnterTheFridge();
barrier.SignalAndWait(); //第三步
fridge.PhaseTaskResult.ThirdResult = fridge.CloseTheDoor();
barrier.SignalAndWait(); //返回每个步骤得到的结果
return fridge.PhaseTaskResult; }, i);
} //最后ContinueWhenAll,输出每个任务记录的结果,释放Barrier
var continueTask = Task.Factory.ContinueWhenAll(tasks, (t) =>
{
foreach (var item in t)
{
Console.Write(string.Format("任务{0}:", t.ToList().IndexOf(item) + ));
Console.WriteLine(item.Result.FirstResult);
Console.Write(string.Format("任务{0}:", t.ToList().IndexOf(item) + ));
Console.WriteLine(item.Result.SecondResult);
Console.Write(string.Format("任务{0}:", t.ToList().IndexOf(item) + ));
Console.WriteLine(item.Result.ThirdResult);
}
Console.WriteLine();
Console.WriteLine("已将全部大象放入全部冰箱");
barrier.Dispose();
}); Console.ReadLine();
}
} /// <summary>
/// 大象
/// </summary>
public class Elephant
{
public String ElephantName { get; set; }
} /// <summary>
/// 冰箱
/// </summary>
public class Fridge
{
public String FridgeName { get; set; } public String ElephantName { get; set; } public PhaseTask PhaseTaskResult = new PhaseTask(); public String OpenTheDoor()
{
return PhaseTaskResult.FirstResult = PhaseTaskResult.PhaseFirst(ElephantName, FridgeName);
} public String EnterTheFridge()
{
return PhaseTaskResult.SecondResult = PhaseTaskResult.PhaseSecond(ElephantName, FridgeName);
} public String CloseTheDoor()
{
return PhaseTaskResult.ThirdResult = PhaseTaskResult.PhaseThird(ElephantName, FridgeName);
}
} /// <summary>
/// 构造大象和冰箱
/// </summary>
public class ElephantsAndFridges
{
public List<Elephant> elephants; public List<Fridge> fridges; public ElephantsAndFridges()
{
elephants = new List<Elephant>()
{
new Elephant() {ElephantName="大象甲" },
new Elephant() {ElephantName="大象乙" },
new Elephant() {ElephantName="大象丙" }
}; fridges = new List<Fridge>()
{
new Fridge(){ FridgeName="冰箱甲"},
new Fridge(){ FridgeName="冰箱乙"},
new Fridge(){ FridgeName="冰箱丙"}
};
}
} /// <summary>
/// 把大象放入冰箱,共需3步
/// 第一步,打开冰箱门
/// 第二步,把大象放进冰箱
/// 第三步,关闭冰箱门
/// 该类提供三个步骤和每个步骤得到的结果
/// </summary>
public class PhaseTask
{
public String FirstResult { get; set; } public String SecondResult { get; set; } public String ThirdResult { get; set; } public String PhaseFirst(string elephantName, string fridgeName)
{
string str = string.Format("第一步:为{0}打开{1}门", elephantName, fridgeName);
Console.WriteLine(str);
return FirstResult = str;
} public String PhaseSecond(string elephantName, string fridgeName)
{
string str = string.Format("第二步:把{0}放入{1}", elephantName, fridgeName);
Console.WriteLine(str);
return SecondResult = str;
} public String PhaseThird(string elephantName, string fridgeName)
{
string str = string.Format("第三步:为{0}关闭{1}门", elephantName, fridgeName);
Console.WriteLine(str);
return ThirdResult = str;
}
}
使用Barrier分三步将大象放入冰箱的更多相关文章
- Postman A请求的返回值作为B请求的入参( 拢共分三步)
- java 调用 C# 类库搞定,三步即可,可以调用任何类及方法,很简单,非常爽啊
java 调用 C# 类库搞定,三步即可,可以调用任何类及方法,很简单,非常爽啊 java 调用 C# 类库搞定,可以调用任何类及方法,很简单,非常爽啊 总体分三步走: 一.准备一个 C# 类库 (d ...
- [其它]iOS 12.2支持电信VoLTE了,中国电信教你如何开通:只要三步
iOS 12.2支持电信VoLTE了,中国电信教你如何开通:只要三步 link :https://baijiahao.baidu.com/s?id=1629039609897267682&wf ...
- 把大象装进冰箱的N种方法
作者:折剑头链接:https://www.zhihu.com/question/49214119/answer/115728034来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...
- Membership三步曲之进阶篇 - 深入剖析Provider Model
Membership 三步曲之进阶篇 - 深入剖析Provider Model 本文的目标是让每一个人都知道Provider Model 是什么,并且能灵活的在自己的项目中使用它. Membershi ...
- Membership三步曲之入门篇 - Membership基础示例
Membership 三步曲之入门篇 - Membership基础示例 Membership三步曲之入门篇 - Membership基础示例 Membership三步曲之进阶篇 - 深入剖析Pro ...
- EC笔记:第三部分:17、使用独立的语句将newed对象放入智能指针
一般的智能指针都是通过一个普通指针来初始化,所以很容易写出以下的代码: #include <iostream> using namespace std; int func1(){ //返回 ...
- java入门第三步之数据库连接
数据库连接可以说是学习web最基础的部分,也是非常重要的一部分,今天我们就来介绍下数据库的连接为下面学习真正的web打下基础 java中连接数据库一般有两种方式: 1.ODBC——Open Datab ...
- [转]Membership三步曲之入门篇 - Membership基础示例
本文转自:http://www.cnblogs.com/jesse2013/p/membership.html Membership三步曲之入门篇 - Membership基础示例 Members ...
随机推荐
- 通过JS动态追加标签,以父评论子评论为例
以下代码前后端交互以Django模板语法为例 先来以伪代码来示意用法: HTML部分: JS动态插入部分代码: 运行之后我们来浏览器看检查打印的内容: 看插入前后打印结果我们可以得知 $title[0 ...
- [转] Slf4j MDC机制
MDC ( Mapped Diagnostic Contexts ),线程安全的诊断日志存放容器. 可用于存放线程的全局日志信息, 通过xml配置后可以打印在日志中,用于日志记录.定位.分析 相关:h ...
- 关于使用pietty或putty终端连接ubuntu虚拟机时报被拒绝连接问题
首先如果要使用终端进行远程连接的ubuntu虚拟机的话,必须保证其虚拟机ip能在window下ping的动.具体的ubuntu网络配置这里不再讲,我这里使用的是NAT连接. 然后检查ssh服务是否有安 ...
- 二维码生成工具类java版
注意:这里我不提供所需jar包的路径,我会把所有引用的jar包显示出来,大家自行Google package com.net.util; import java.awt.BasicStroke; im ...
- HDU 3642 求体积交集
Get The Treasury 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=3642 Problem Description Jack knows ...
- C++编写DLL文件
动态链接库DLL文件与EXE文件一样也是可执行文件,但是DLL也被称为库,因为里面封装了各种类.函数之类的东西,就像一个库一样,存着很多东西,主要是用来调用的.调用方式主要分为两种:隐式(通过lib文 ...
- 编写程序模拟strlwr()和strupr()函数功能
strlwr(字符串)strlwr()的作用是将字符串中大写字母转换成小写字母 strupr(字符串)strupr()的作用是将字符串中小写字母转换成大写字母 /* strlwr(字符串) strlw ...
- 基于白名单的Payload
利用 Msiexec 命令DLL反弹 Msiexec是Windows Installer的一部分.用于安装Windows Installer安装包(MSI),一般在运行Microsoft Update ...
- 怎样通过id属性值获取元素节点
方法1: 使用document.getElementById(); 方法2: 使用document.querySelector(); document.getElementById("app ...
- Python实现乘法表——在列表里进行for循环设初值
代码:最大的收获是二维列表的实现:[0]*9结果是[0,0,0,0,0,0,0,0,0,0],再加上for i in range(9),代表是9行[0,0,0,0,0,0,0,0,0,0],也就是9* ...