C# 关于 barierr 心得

理解

Barrier与ContinueWith都是用于并发编程的工具,但它们的设计目的和应用场景有本质区别。Barrier侧重于多线程间的同步协调,而ContinueWith则用于定义异步操作完成后的后续动作。

Barrier ‌ 是一个同步原语,用于协调多个线程的执行进度。它像一道关卡,所有参与的线程必须到达屏障点后等待,直到所有线程都到达,才能同时通过并继续执行。这通常用于需要阶段性同步的并行算法,例如在多轮迭代计算中确保所有线程完成当前阶段后再进入下一阶段。‌Barrier 支持多阶段操作,并允许在每个阶段完成后执行回调动作。其核心方法 SignalAndWait() 使当前线程通知屏障自己已到达并等待其他线程。如果某个线程未调用此方法,会导致死锁。‌

ContinueWith ‌ 是Task类的一个方法,用于定义异步操作完成后的后续操作。当一个任务(Task)执行完毕时,可以指定一个委托(Action或Func)通过 ContinueWith 来执行,这类似于"链式调用"或回调机制。它常用于处理异步操作的结果或执行清理工作,例如在文件读取完成后更新UI或处理数据。‌ ContinueWith 不涉及线程同步,而是专注于异步流程的编排。

两者的主要区别在于:

  • 作用范围‌:Barrier 用于多线程间的同步,确保线程在特定点对齐;ContinueWith 用于单个异步任务的后续操作链。
  • 使用场景‌:Barrier 适用于需要所有线程协作的并行计算(如迭代算法);ContinueWith 适用于异步编程中的流程控制(如I/O操作后的处理)。
  • 同步机制‌:Barrier 是阻塞式同步,线程会等待其他线程到达;ContinueWith 是非阻塞的,任务完成后自动触发后续操作。

在实际编程中,如果需要协调多个线程的阶段性执行,应选择 Barrier;如果需要定义异步操作的后续步骤,则应使用 ContinueWith。两者可以结合使用,例如在 Barrier 的阶段回调中启动新的异步任务,但它们的核心职责不同。‌

实例

cs 复制代码
    internal class Program
    {
        static string[] words1 = new string[] { "brown", "jumps", "the", "fox", "quick" };
        static string[] words2 = new string[] { "dog", "lazy", "the", "over" };
        static string solution = "the quick brown fox jumps over the lazy dog.";

        static bool success = false;
        static Barrier barrier = new Barrier(2, (b) =>
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < words1.Length; i++)
            {
                sb.Append(words1[i]);
                sb.Append(" ");
            }
            for (int i = 0; i < words2.Length; i++)
            {
                sb.Append(words2[i]);

                if (i < words2.Length - 1)
                    sb.Append(" ");
            }
            sb.Append(".");
#if TRACE
            System.Diagnostics.Trace.WriteLine(sb.ToString());
#endif
            Console.CursorLeft = 0;
            Console.Write("Current phase: {0}", barrier.CurrentPhaseNumber);
            if (String.CompareOrdinal(solution, sb.ToString()) == 0)
            {
                success = true;
                Console.WriteLine($"\r\nThe solution was found in {barrier.CurrentPhaseNumber} attempts");
            }
        });



        static void Main(string[] args)
        {
            Thread t1 = new Thread(() => Solve(words1));
            Thread t2 = new Thread(() => Solve(words2));
            t1.Start();
            t2.Start();

            Console.ReadLine();
        }

        static void Solve(string[] wordArray)
        {
            while (success == false)
            {
                Random random = new Random();
                for (int i = wordArray.Length - 1; i > 0; i--)
                {
                    int swapIndex = random.Next(i + 1);
                    string temp = wordArray[i];
                    wordArray[i] = wordArray[swapIndex];
                    wordArray[swapIndex] = temp;
                }

                barrier.SignalAndWait();
            }
        }
    }
相关推荐
Knight_AL4 分钟前
阿里《Java 开发手册》下的对象构建与赋值规范实践
java·开发语言
lsx2024065 分钟前
SQL LIKE 操作符详解
开发语言
微爱帮监所写信寄信13 分钟前
微爱帮监狱寄信写信工具照片高清处理技术架构
开发语言·人工智能·网络协议·微信·php
小码编匠15 分钟前
工业视觉 C# + OpenCvSharp 的模板匹配实战
后端·c#·.net
报错小能手23 分钟前
数据结构 字典树
开发语言·数据结构
XLYcmy33 分钟前
高级密码生成器程序详解:专门设计用于生成基于用户个人信息的密码猜测组合
开发语言·数据结构·python·网络安全·数据安全·源代码·口令安全
独自破碎E41 分钟前
Leetcode862和至少为K的最短子数组
java·开发语言
qq_3707730944 分钟前
x64dbg 脚本常用命令
开发语言·x64dbg
军军君011 小时前
Three.js基础功能学习五:雾与渲染目标
开发语言·前端·javascript·学习·3d·前端框架·three
charlie1145141911 小时前
FreeRTOS:软件定时器(Software Timers)与时间管理
开发语言·笔记·学习·freertos·实时操作系统·工程