使用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     }

 

posted on 2018-05-12 11:25  庭前花满留晚照  阅读(282)  评论(0编辑  收藏  举报

导航