1. 程式人生 > >使用Barrier分三步將大象放入冰箱

使用Barrier分三步將大象放入冰箱

PE san idg 指示 efault ridge private null BE

  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分三步將大象放入冰箱