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();
            }
        }
    }
相关推荐
哈哈不让取名字1 天前
基于C++的爬虫框架
开发语言·c++·算法
花间相见1 天前
【JAVA开发】—— Nginx服务器
java·开发语言·nginx
初级代码游戏1 天前
C#:程序发布的大小控制 裁剪 压缩
c#·.net·dotnet·压缩·大小·发布·裁剪
扶苏-su1 天前
Java---Properties 类
java·开发语言
一条咸鱼_SaltyFish1 天前
远程鉴权中心设计:HTTP 与 gRPC 的技术决策与实践
开发语言·网络·网络协议·程序人生·http·开源软件·个人开发
我即将远走丶或许也能高飞1 天前
vuex 和 pinia 的学习使用
开发语言·前端·javascript
沐知全栈开发1 天前
SQL LEN() 函数详解
开发语言
钟离墨笺1 天前
Go语言--2go基础-->基本数据类型
开发语言·前端·后端·golang
小郭团队1 天前
1_7_五段式SVPWM (传统算法反正切+DPWM3)算法理论与 MATLAB 实现详解
开发语言·嵌入式硬件·算法·matlab·dsp开发
C+-C资深大佬1 天前
C++风格的命名转换
开发语言·c++