Barrier 是一個對象,它可以在并行操作中的所有任務都達到相應的關卡之前,阻止各個任務繼續執行。 如果并行操作是分階段執行的,并且每一階段要求各任務之間進行同步,則可以使用該對象。 ——MSDN
按照我的理解Barrier其實就是將多個任務同步,而同步需要一個屏障或者是關卡,那么其方法SignalAndWait()就是屏障的作用;
我們來模擬現實中例子,做火車就是很好的參照,大家知道,火車的車次有個發車點,到了那個時間點才能發車,那我們稍微修改下,人到齊后才能發車。
1.首先從家出發,在路上實現:
PRivate static void OnRoading(string name, int costTime) { Console.WriteLine(string.Format("[{0}]在去火車站路上.....,花費{1}小時.", name, costTime)); Thread.Sleep(new TimeSpan(0, 0, costTime)); }
2.達到火車站,等候火車,這相當于同步任務,(所模擬的是,乘火車到人到齊后才能發車)
private static void OnStationing(string name) { Console.WriteLine(string.Format("[{0}]到達火車站,正在安檢等候火車.....", name)); gate.SignalAndWait(); }
3.人到齊后,發車
private static void OnTraining(string name) { Console.WriteLine(string.Format("[{0}]乘坐火車離開.....", name)); }
完整代碼實現
static Barrier gate; static void Main(string[] args) { try { ToStationWorkTyp2(); } catch (Exception ex) { Console.WriteLine(string.Format("Exception Message:{0}", ex.Message.Trim())); } finally { Console.ReadLine(); } } private static void ToStationWorkTyp2() { gate = new Barrier(3); Task _taskA = Task.Factory.StartNew(() => { OnRoading("personA", 2); OnStationing("personA"); OnTraining("personA"); }); Task _taskB = Task.Factory.StartNew(() => { OnRoading("personB", 5); OnStationing("personB"); OnTraining("personB"); }); Task _taskC = Task.Factory.StartNew(() => { OnRoading("personC", 3); OnStationing("personC"); OnTraining("personC"); }); Task.WaitAll(_taskA, _taskB, _taskC); } private static void OnTraining(string name) { Console.WriteLine(string.Format("[{0}]乘坐火車離開.....", name)); } private static void OnStationing(string name) { Console.WriteLine(string.Format("[{0}]到達火車站,正在安檢等候火車.....", name)); gate.SignalAndWait(); } private static void OnRoading(string name, int costTime) { Console.WriteLine(string.Format("[{0}]在去火車站路上.....,花費{1}小時.", name, costTime)); Thread.Sleep(new TimeSpan(0, 0, costTime)); }
代碼效果
另外一種代碼實現
using System;using System.Collections;using System.Collections.Generic;using System.Diagnostics;using System.Linq;using System.Threading;using System.Threading.Tasks;namespace PLinq{ class Program { static Barrier gate; static void Main(string[] args) { try { ToStationWorkTyp1(); } catch (Exception ex) { Console.WriteLine(string.Format("Exception Message:{0}", ex.Message.Trim())); } finally { Console.ReadLine(); } } private static void ToStationWorkTyp1() { gate = new Barrier(3); Task _taskA = Task.Factory.StartNew(() => ToStation("PersonA", 2)); Task _taskB = Task.Factory.StartNew(() => ToStation("PersonB", 3)); Task _taskC = Task.Factory.StartNew(() => ToStation("PersonC", 5)); Task.WaitAll(_taskA, _taskB, _taskC); } private static void ToStation(string name, int costTime) { Console.WriteLine(string.Format("[{0}]在去火車站路上.....,花費{1}小時.", name, costTime)); Thread.Sleep(new TimeSpan(0, 0, costTime)); Console.WriteLine(string.Format("[{0}]到達火車站,正在安檢等候火車.....", name)); gate.SignalAndWait(); Console.WriteLine(string.Format("[{0}]乘坐火車離開.....", name)); } }}同樣的實現效果
新聞熱點
疑難解答