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();
            }
        }
    }
相关推荐
yuniko-n10 小时前
【Java】关于容器选型:Deque、PriorityQueue、LinkedList
java·开发语言
扶风ff10 小时前
练题簿在线免费刷题:创建个人任务,把刷题、听题和模考目标放到每天的学习中
开发语言·javascript·学习·小程序
yuniko-n10 小时前
【JUC】wait 和 sleep
java·开发语言
kimnoic10 小时前
Python常见模块及其用法示例详解
开发语言·python
程序员-Benothing10 小时前
Linux文本排序统计命令:sort、uniq、wc、cut、tr实战
java·开发语言·算法
CRMEB10 小时前
前后端技术栈全面换代!CRMEB 多商户(Java)v3.0更新预告
java·开发语言
JQLvopkk10 小时前
HslCommunication,一个工具测遍所有 PLC
开发语言·人工智能·c#·交互
阿狗童鞋10 小时前
Python爬虫进阶实战指南
开发语言·爬虫·python
下页、再停留10 小时前
【C#桌面客户端系列学习-7】数据查询展示
开发语言·c#·visual studio
皓月盈江11 小时前
Go读写TXT文件
开发语言·后端·golang·go·读写txt文件·bufio·go读写txt