Barrier クラス

定義

複数のタスクが複数のフェーズを通じて並行してアルゴリズムに対して協調的に動作できるようにします。

public ref class Barrier : IDisposable
public class Barrier : IDisposable
[System.Runtime.InteropServices.ComVisible(false)]
public class Barrier : IDisposable
type Barrier = class
    interface IDisposable
[<System.Runtime.InteropServices.ComVisible(false)>]
type Barrier = class
    interface IDisposable
Public Class Barrier
Implements IDisposable
継承
Barrier
属性
実装

バリアを使用する方法の例を次に示します。

using System;
using System.Threading;
using System.Threading.Tasks;

class BarrierDemo
{
    // Demonstrates:
    //      Barrier constructor with post-phase action
    //      Barrier.AddParticipants()
    //      Barrier.RemoveParticipant()
    //      Barrier.SignalAndWait(), incl. a BarrierPostPhaseException being thrown
    static void BarrierSample()
    {
        int count = 0;

        // Create a barrier with three participants
        // Provide a post-phase action that will print out certain information
        // And the third time through, it will throw an exception
        Barrier barrier = new Barrier(3, (b) =>
        {
            Console.WriteLine("Post-Phase action: count={0}, phase={1}", count, b.CurrentPhaseNumber);
            if (b.CurrentPhaseNumber == 2) throw new Exception("D'oh!");
        });

        // Nope -- changed my mind.  Let's make it five participants.
        barrier.AddParticipants(2);

        // Nope -- let's settle on four participants.
        barrier.RemoveParticipant();

        // This is the logic run by all participants
        Action action = () =>
        {
            Interlocked.Increment(ref count);
            barrier.SignalAndWait(); // during the post-phase action, count should be 4 and phase should be 0
            Interlocked.Increment(ref count);
            barrier.SignalAndWait(); // during the post-phase action, count should be 8 and phase should be 1

            // The third time, SignalAndWait() will throw an exception and all participants will see it
            Interlocked.Increment(ref count);
            try
            {
                barrier.SignalAndWait();
            }
            catch (BarrierPostPhaseException bppe)
            {
                Console.WriteLine("Caught BarrierPostPhaseException: {0}", bppe.Message);
            }

            // The fourth time should be hunky-dory
            Interlocked.Increment(ref count);
            barrier.SignalAndWait(); // during the post-phase action, count should be 16 and phase should be 3
        };

        // Now launch 4 parallel actions to serve as 4 participants
        Parallel.Invoke(action, action, action, action);

        // This (5 participants) would cause an exception:
        // Parallel.Invoke(action, action, action, action, action);
        //      "System.InvalidOperationException: The number of threads using the barrier
        //      exceeded the total number of registered participants."

        // It's good form to Dispose() a barrier when you're done with it.
        barrier.Dispose();
    }
}
Imports System.Threading
Imports System.Threading.Tasks

Module BarrierSample

    ' Demonstrates:
    ' Barrier constructor with post-phase action
    ' Barrier.AddParticipants()
    ' Barrier.RemoveParticipant()
    ' Barrier.SignalAndWait(), incl. a BarrierPostPhaseException being thrown
    Sub Main()
        Dim count As Integer = 0

        ' Create a barrier with three participants
        ' Provide a post-phase action that will print out certain information
        ' And the third time through, it will throw an exception
        Dim barrier As New Barrier(3,
                                   Sub(b)
                                       Console.WriteLine("Post-Phase action: count={0}, phase={1}", count, b.CurrentPhaseNumber)
                                       If b.CurrentPhaseNumber = 2 Then
                                           Throw New Exception("D'oh!")
                                       End If
                                   End Sub)

        ' Nope -- changed my mind. Let's make it five participants.
        barrier.AddParticipants(2)

        ' Nope -- let's settle on four participants.
        barrier.RemoveParticipant()


        ' This is the logic run by all participants
        Dim action As Action =
            Sub()
                Interlocked.Increment(count)
                barrier.SignalAndWait()
                ' during the post-phase action, count should be 4 and phase should be 0

                Interlocked.Increment(count)
                barrier.SignalAndWait()
                ' during the post-phase action, count should be 8 and phase should be 1

                ' The third time, SignalAndWait() will throw an exception and all participants will see it
                Interlocked.Increment(count)
                Try
                    barrier.SignalAndWait()
                Catch bppe As BarrierPostPhaseException
                    Console.WriteLine("Caught BarrierPostPhaseException: {0}", bppe.Message)
                End Try

                ' The fourth time should be hunky-dory
                Interlocked.Increment(count)
                ' during the post-phase action, count should be 16 and phase should be 3
                barrier.SignalAndWait()

            End Sub

        ' Now launch 4 parallel actions to serve as 4 participants
        Parallel.Invoke(action, action, action, action)

        ' This (5 participants) would cause an exception:
        '   Parallel.Invoke(action, action, action, action, action)
        ' "System.InvalidOperationException: The number of threads using the barrier
        ' exceeded the total number of registered participants."

        ' It's good form to Dispose() a barrier when you're done with it.
        barrier.Dispose()
    End Sub
End Module

注釈

タスクのグループは、一連のフェーズを進めることで連携します。グループ内の各フェーズは、特定のフェーズで Barrier に到着したことを通知し、他のすべてのフェーズが到着するのを暗黙的に待機します。 同じ Barrier を複数のフェーズに使用できます。

コンストラクター

名前 説明
Barrier(Int32, Action<Barrier>)

Barrier クラスの新しいインスタンスを初期化します。

Barrier(Int32)

Barrier クラスの新しいインスタンスを初期化します。

プロパティ

名前 説明
CurrentPhaseNumber

バリアの現在のフェーズの数を取得します。

ParticipantCount

バリア内の参加者の合計数を取得します。

ParticipantsRemaining

現在のフェーズでまだ通知されていないバリア内の参加者の数を取得します。

メソッド

名前 説明
AddParticipant()

追加の参加者が存在することを Barrier に通知します。

AddParticipants(Int32)

追加の参加者が存在することを Barrier に通知します。

Dispose()

Barrier クラスの現在のインスタンスで使用されているすべてのリソースを解放します。

Dispose(Boolean)

Barrierによって使用されるアンマネージ リソースを解放し、必要に応じてマネージド リソースを解放します。

Equals(Object)

指定したオブジェクトが現在のオブジェクトと等しいかどうかを判断します。

(継承元 Object)
GetHashCode()

既定のハッシュ関数として機能します。

(継承元 Object)
GetType()

現在のインスタンスの Type を取得します。

(継承元 Object)
MemberwiseClone()

現在の Objectの簡易コピーを作成します。

(継承元 Object)
RemoveParticipant()

参加者が 1 人少なくなることを Barrier に通知します。

RemoveParticipants(Int32)

参加者が少なくなることを Barrier に通知します。

SignalAndWait()

参加者がバリアに到達したことを通知し、他のすべての参加者もバリアに到達するまで待機します。

SignalAndWait(CancellationToken)

参加者がバリアに到達したことを通知し、キャンセル トークンを観察しながら、他のすべての参加者がバリアに到達するのを待機します。

SignalAndWait(Int32, CancellationToken)

参加者がバリアに到達し、キャンセル トークンを監視しながら、32 ビット符号付き整数を使用してタイムアウトを測定し、他のすべての参加者もバリアに到達するまで待機することを通知します。

SignalAndWait(Int32)

参加者がバリアに到達し、32 ビット符号付き整数を使用してタイムアウトを測定し、他のすべての参加者もバリアに到達するまで待機することを通知します。

SignalAndWait(TimeSpan, CancellationToken)

参加者がバリアに到達し、キャンセル トークンを観察しながら、 TimeSpan オブジェクトを使用して時間間隔を測定し、他のすべての参加者がバリアに到達するまで待機することを通知します。

SignalAndWait(TimeSpan)

参加者がバリアに到達したことを通知し、他のすべての参加者がバリアに到達するまで待機します。 TimeSpan オブジェクトを使用して時間間隔を測定します。

ToString()

現在のオブジェクトを表す文字列を返します。

(継承元 Object)

適用対象

スレッド セーフ

Barrierのすべてのパブリック メンバーと保護されたメンバーはスレッド セーフであり、Dispose を除き、複数のスレッドから同時に使用できます。Dispose は、Barrierに対する他のすべての操作が完了したときにのみ使用する必要があります。

こちらもご覧ください