Barrier 类
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
使多个任务能够采用并行方式依据某种算法在多个阶段中协同工作。
public ref class Barrier : IDisposablepublic class Barrier : IDisposable[System.Runtime.InteropServices.ComVisible(false)]
public class Barrier : IDisposabletype Barrier = class
    interface IDisposable[<System.Runtime.InteropServices.ComVisible(false)>]
type Barrier = class
    interface IDisposablePublic 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() | 通知 Barrier,告知其将会有另一个参与者。 | 
| AddParticipants(Int32) | 通知 Barrier,告知其将会有多个其他参与者。 | 
| Dispose() | 释放 Barrier 类的当前实例所使用的所有资源。 | 
| Dispose(Boolean) | 释放由 Barrier 占用的非托管资源,还可以另外再释放托管资源。 | 
| Equals(Object) | 确定指定对象是否等于当前对象。(继承自 Object) | 
| GetHashCode() | 作为默认哈希函数。(继承自 Object) | 
| GetType() | 获取当前实例的 Type。(继承自 Object) | 
| MemberwiseClone() | 创建当前 Object 的浅表副本。(继承自 Object) | 
| RemoveParticipant() | 通知 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 时才使用。