Barrier Class
Definition
Enables multiple tasks to cooperatively work on an algorithm in parallel through multiple phases.
public ref class Barrier : IDisposable
[System.Runtime.InteropServices.ComVisible(false)]
public class Barrier : IDisposable
type Barrier = class
interface IDisposable
Public Class Barrier
Implements IDisposable
- Inheritance
-
Barrier
- Attributes
- Implements
Examples
The following example shows how to use a 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
Remarks
A group of tasks cooperate by moving through a series of phases, where each in the group signals it has arrived at the Barrier in a given phase and implicitly waits for all others to arrive. The same Barrier can be used for multiple phases.
Constructors
Barrier(Int32) |
Initializes a new instance of the Barrier class. |
Barrier(Int32, Action<Barrier>) |
Initializes a new instance of the Barrier class. |
Properties
CurrentPhaseNumber |
Gets the number of the barrier's current phase. |
ParticipantCount |
Gets the total number of participants in the barrier. |
ParticipantsRemaining |
Gets the number of participants in the barrier that haven't yet signaled in the current phase. |
Methods
AddParticipant() |
Notifies the Barrier that there will be an additional participant. |
AddParticipants(Int32) |
Notifies the Barrier that there will be additional participants. |
Dispose() |
Releases all resources used by the current instance of the Barrier class. |
Dispose(Boolean) |
Releases the unmanaged resources used by the Barrier, and optionally releases the managed resources. |
Equals(Object) |
Determines whether the specified object is equal to the current object. (Inherited from Object) |
GetHashCode() |
Serves as the default hash function. (Inherited from Object) |
GetType() |
Gets the Type of the current instance. (Inherited from Object) |
MemberwiseClone() |
Creates a shallow copy of the current Object. (Inherited from Object) |
RemoveParticipant() |
Notifies the Barrier that there will be one less participant. |
RemoveParticipants(Int32) |
Notifies the Barrier that there will be fewer participants. |
SignalAndWait() |
Signals that a participant has reached the barrier and waits for all other participants to reach the barrier as well. |
SignalAndWait(CancellationToken) |
Signals that a participant has reached the barrier and waits for all other participants to reach the barrier, while observing a cancellation token. |
SignalAndWait(Int32) |
Signals that a participant has reached the barrier and waits for all other participants to reach the barrier as well, using a 32-bit signed integer to measure the timeout. |
SignalAndWait(Int32, CancellationToken) |
Signals that a participant has reached the barrier and waits for all other participants to reach the barrier as well, using a 32-bit signed integer to measure the timeout, while observing a cancellation token. |
SignalAndWait(TimeSpan) |
Signals that a participant has reached the barrier and waits for all other participants to reach the barrier as well, using a TimeSpan object to measure the time interval. |
SignalAndWait(TimeSpan, CancellationToken) |
Signals that a participant has reached the barrier and waits for all other participants to reach the barrier as well, using a TimeSpan object to measure the time interval, while observing a cancellation token. |
ToString() |
Returns a string that represents the current object. (Inherited from Object) |
Applies to
Thread Safety
All public and protected members of Barrier are thread-safe and may be used concurrently from multiple threads, with the exception of Dispose, which must only be used when all other operations on the Barrier have completed.