使用Barrier分三步将大象放入冰箱
Posted 庭前花满留晚照
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Barrier分三步将大象放入冰箱相关的知识,希望对你有一定的参考价值。
1 class Program 2 { 3 //构造大象和冰箱 4 private static ElephantsAndFridges elephantsAndFridges = new ElephantsAndFridges(); 5 6 static void Main(string[] args) 7 { 8 int taskCnt = 3; 9 10 //此处有3个Task来完成工作(注意多任务与多线程及堆栈数据边界) 11 //并将每个任务的执行结果返回 12 Task<PhaseTask>[] tasks = new Task<PhaseTask>[taskCnt]; 13 14 //使多个任务能够采用并行方式依据某种算法在多个阶段中协同工作 15 // 参数: 16 // participantCount: 17 // 参与线程的数量。 18 // 19 // postPhaseAction: 20 // 每个阶段完成之后执行。 可传递 null ,以指示不执行任何操作 21 Barrier barrier = new Barrier(taskCnt, (b) => 22 { 23 Console.WriteLine(string.Format("第{0}阶段已完成", b.CurrentPhaseNumber + 1)); 24 Console.WriteLine(); 25 }); 26 for (int i = 0; i < taskCnt; i++) 27 { 28 //使用Task工厂启3个任务 29 tasks[i] = Task<PhaseTask>.Factory.StartNew((obj) => 30 { 31 int cnt = (int)obj; 32 33 //一个任务一个冰箱(冰箱具有打开和关闭冰箱门及放大象操作) 34 Fridge fridge = new Fridge(); 35 36 //注:此处不能用i,存在执行顺序问题 37 //例如:还未开始从elephantsAndFridges中拿数据,i的值就已经加1了,此时拿的就是i+1位置,而非i位置的数据 38 fridge.ElephantName = elephantsAndFridges.elephants.ElementAtOrDefault(cnt).ElephantName; 39 fridge.FridgeName = elephantsAndFridges.fridges.ElementAtOrDefault(cnt).FridgeName; 40 41 //第一步 42 fridge.PhaseTaskResult.FirstResult = fridge.OpenTheDoor(); 43 //用信号通知的参与者已达到屏障和所有其他参与者到达屏障也会等待 44 barrier.SignalAndWait(); 45 46 //第二部 47 fridge.PhaseTaskResult.SecondResult = fridge.EnterTheFridge(); 48 barrier.SignalAndWait(); 49 50 //第三部 51 fridge.PhaseTaskResult.ThirdResult = fridge.CloseTheDoor(); 52 barrier.SignalAndWait(); 53 54 //返回每个步骤得到的结果 55 return fridge.PhaseTaskResult; 56 57 }, i); 58 } 59 60 //最后ContinueWhenAll,输出每个任务记录的结果,释放Barrier 61 var continueTask = Task.Factory.ContinueWhenAll(tasks, (t) => 62 { 63 foreach (var item in t) 64 { 65 Console.Write(string.Format("任务{0}:", t.ToList().IndexOf(item) + 1)); 66 Console.WriteLine(item.Result.FirstResult); 67 Console.Write(string.Format("任务{0}:", t.ToList().IndexOf(item) + 1)); 68 Console.WriteLine(item.Result.SecondResult); 69 Console.Write(string.Format("任务{0}:", t.ToList().IndexOf(item) + 1)); 70 Console.WriteLine(item.Result.ThirdResult); 71 } 72 Console.WriteLine(); 73 Console.WriteLine("已将全部大象放入全部冰箱"); 74 barrier.Dispose(); 75 }); 76 77 Console.ReadLine(); 78 } 79 } 80 81 /// <summary> 82 /// 大象 83 /// </summary> 84 public class Elephant 85 { 86 public String ElephantName { get; set; } 87 } 88 89 /// <summary> 90 /// 冰箱 91 /// </summary> 92 public class Fridge 93 { 94 public String FridgeName { get; set; } 95 96 public String ElephantName { get; set; } 97 98 public PhaseTask PhaseTaskResult = new PhaseTask(); 99 100 public String OpenTheDoor() 101 { 102 return PhaseTaskResult.FirstResult = PhaseTaskResult.PhaseFirst(ElephantName, FridgeName); 103 } 104 105 public String EnterTheFridge() 106 { 107 return PhaseTaskResult.SecondResult = PhaseTaskResult.PhaseSecond(ElephantName, FridgeName); 108 } 109 110 public String CloseTheDoor() 111 { 112 return PhaseTaskResult.ThirdResult = PhaseTaskResult.PhaseThird(ElephantName, FridgeName); 113 } 114 } 115 116 /// <summary> 117 /// 构造大象和冰箱 118 /// </summary> 119 public class ElephantsAndFridges 120 { 121 public List<Elephant> elephants; 122 123 public List<Fridge> fridges; 124 125 public ElephantsAndFridges() 126 { 127 elephants = new List<Elephant>() 128 { 129 new Elephant() {ElephantName="大象甲" }, 130 new Elephant() {ElephantName="大象乙" }, 131 new Elephant() {ElephantName="大象丙" } 132 }; 133 134 fridges = new List<Fridge>() 135 { 136 new Fridge(){ FridgeName="冰箱甲"}, 137 new Fridge(){ FridgeName="冰箱乙"}, 138 new Fridge(){ FridgeName="冰箱丙"} 139 }; 140 } 141 } 142 143 /// <summary> 144 /// 把大象放入冰箱,共需3步 145 /// 第一步,打开冰箱门 146 /// 第二部,把大象放进冰箱 147 /// 第三部,关闭冰箱门 148 /// 该类提供三个步骤和每个步骤得到的结果 149 /// </summary> 150 public class PhaseTask 151 { 152 public String FirstResult { get; set; } 153 154 public String SecondResult { get; set; } 155 156 public String ThirdResult { get; set; } 157 158 public String PhaseFirst(string elephantName, string fridgeName) 159 { 160 string str = string.Format("第一步:为{0}打开{1}门", elephantName, fridgeName); 161 Console.WriteLine(str); 162 return FirstResult = str; 163 } 164 165 public String PhaseSecond(string elephantName, string fridgeName) 166 { 167 string str = string.Format("第二步:把{0}放入{1}", elephantName, fridgeName); 168 Console.WriteLine(str); 169 return SecondResult = str; 170 } 171 172 public String PhaseThird(string elephantName, string fridgeName) 173 { 174 string str = string.Format("第三步:为{0}关闭{1}门", elephantName, fridgeName); 175 Console.WriteLine(str); 176 return ThirdResult = str; 177 } 178 }
以上是关于使用Barrier分三步将大象放入冰箱的主要内容,如果未能解决你的问题,请参考以下文章