[C#][VB.NET].NET 4.0 Barrier Class

  • 11712
  • 0
  • C#
  • 2010-01-20

.NET 4.0 Barrier Class

Introduction

.NET 4.0後在System.Threading命名空間中新加入了Barrier類別,該類別的功能就如同字面意義一樣,可視為是一個關卡或是剪票口。透過Barrier Class我們可以管制執行緒的運作,做到執行緒同步的效果。
 

字面意思

Barrier [`bærIL]

n.剪票口;海關關卡;障礙物;路障,柵欄
 

Support

  • .NET Framework 4.0 (C# 4.0、VB.NET 10.0) or latter
     

Assembly

System (in System.dll)
 

Namespace

System.Threading
 

Barrier Class

Barrier Class在使用上十分的簡單,只要宣告Barrier物件並在建構函式帶入participantCount(簡單的說就是要等待的執行緒個數),並在要同步的點叫用SignalAndWait即可。

image

 

執行緒會在叫用SignalAndWait後會暫停運行,等待所有要參與的執行緒都到了同步點才繼續往下運行。

舉個例子來看,假設今天Charlie、Mac、Dennis三個人相約要去西雅圖喝咖啡。由於三個人的住的地區不盡相同,且車子都需要加油,因此他們約在途中會經過的加油站待會合後一同前往。

 image

 

這樣的情境我們可以透過Thread與Barrier用程式加以模擬出來

VB.NET

Imports System.Threading

Module Module1

    Private sync As Barrier

    Sub Main(ByVal args() As String)
        sync = New Barrier(3)

        Dim charlie = New Thread(Sub() DriveToBoston("Charlie", TimeSpan.FromSeconds(1)))
        charlie.Start()
        Dim mac = New Thread(Sub() DriveToBoston("Mac", TimeSpan.FromSeconds(2)))
        mac.Start()
        Dim dennis = New Thread(Sub() DriveToBoston("Dennis", TimeSpan.FromSeconds(3)))
        dennis.Start()

        charlie.Join()
        mac.Join()
        dennis.Join()

        Console.ReadKey()
    End Sub

    Sub DriveToBoston(ByVal name As String, ByVal timeToGasStation As TimeSpan)

        Console.WriteLine("[{0}] Leaving House", name)

        ' Perform some work
        Thread.Sleep(timeToGasStation)
        Console.WriteLine("[{0}] Arrived at Gas Station", name)

        ' Need to sync here
        sync.SignalAndWait()

        ' Perform some more work
        Console.WriteLine("[{0}] Leaving for Gas Station", name)

    End Sub

End Module

 

 

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace BarrierDemo
{
    class Program
    {
        static Barrier sync;

        static void Main(string[] args)
        {
            sync = new Barrier(3);

            var charlie = new Thread(() => DriveToBoston("Charlie", TimeSpan.FromSeconds(1))); charlie.Start();
            var mac = new Thread(() => DriveToBoston("Mac", TimeSpan.FromSeconds(2))); mac.Start();
            var dennis = new Thread(() => DriveToBoston("Dennis", TimeSpan.FromSeconds(3))); dennis.Start();

            charlie.Join();
            mac.Join();
            dennis.Join();

            Console.ReadKey();
        }

        static void DriveToBoston(string name, TimeSpan timeToGasStation)
        {
            Console.WriteLine("[{0}] Leaving House", name);

            // Perform some work
            Thread.Sleep(timeToGasStation);
            Console.WriteLine("[{0}] Arrived at Gas Station", name);

            // Need to sync here
            sync.SignalAndWait();

            // Perform some more work
            Console.WriteLine("[{0}] Leaving for Gas Station", name);

        }
    }
}

 

 

運行結果
image

 

若是不使用Barrier去同步,這邊我們可以拿掉sync.SignalAndWait()再做一次運行,則三個人就會變成各自前往西雅圖喝咖啡了。
image

 

Link