Barrier クラス

定義

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

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)

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

Barrier(Int32, Action<Barrier>)

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

プロパティ

CurrentPhaseNumber

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

ParticipantCount

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

ParticipantsRemaining

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

メソッド

AddParticipant()

参加要素が 1 つ追加されることを 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)

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

SignalAndWait(Int32, CancellationToken)

取り消しトークンを観察すると同時に、32 ビット符号付き整数を使用してタイムアウトを計測し、参加要素がバリアに到達し、他のすべての参加要素もバリアに到達するまで待機することを通知します。

SignalAndWait(TimeSpan)

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

SignalAndWait(TimeSpan, CancellationToken)

取り消しトークンを観察すると同時に、TimeSpan オブジェクトを使用して時間間隔を計測し、参加要素がバリアに到達し、他のすべての参加要素もバリアに到達するまで待機することを通知します。

ToString()

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

(継承元 Object)

適用対象

スレッド セーフ

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

こちらもご覧ください