面向云技术架构 - 痴者工良

  • 首页
  • 工良写的电子书
    • kubernetes 教程
    • 从 C# 入门 Kafka
    • 多线程和异步
    • 动态编程-反射、特性、AOP
    • 表达式树
  • 本站文章导航
  • 隐私政策
愿有人陪你颠沛流离
遇到能让你付出的事物或者人,都是一种运气。
能遇到,就该珍惜。或许你们最终没能在一起,但你会切实地感受到力量。
正因为这样,那段相遇才变得有价值,才没有辜负这世间的每一段相遇。
  1. 首页
  2. .NET
  3. 正文

C#多线程(8):线程完成数

2020年4月19日 1400点热度 0人点赞 0条评论
内容纲要

  • 解决一个问题
    • CountdownEvent 类
    • 构造函数和方法
    • 示例

解决一个问题

假如,程序需要向一个 Web 发送 5 次请求,受网路波动影响,有一定几率请求失败。如果失败了,就需要重试。

示例代码如下:

    class Program
    {
        private static int count = 0;
        static void Main(string[] args)
        {
            for (int i = 0; i 
                {
                    HttpRequest();
                }).Start();
                return;
            }
            // 完成一次任务,+1
            Interlocked.Add(ref count,1);
            Console.WriteLine($完成任务,count={count});
        }
    }

代码太糟糕了,但我们可以使用 CountdownEvent 类来改造它。

CountdownEvent 类

表示在计数变为零时处于有信号状态的同步基元。

也就是说,设定一个计数器,每个线程完成后,就会减去 1 ,当计数器为 0 时,代表所有线程都已经完成了任务。

构造函数和方法

CountdownEvent 类的构造函数如下:

构造函数 说明
CountdownEvent(Int32) 使用指定计数初始化 CountdownEvent 类的新实例。

CountdownEvent 类的常用方法如下:

方法 说明
AddCount() 将 CountdownEvent 的当前计数加 1。
AddCount(Int32) 将 CountdownEvent 的当前计数增加指定值。
Reset() 将 CurrentCount 重置为 InitialCount 的值。
Reset(Int32) 将 InitialCount 属性重新设置为指定值。
Signal() 向 CountdownEvent 注册信号,同时减小 CurrentCount 的值。
Signal(Int32) 向 CountdownEvent 注册多个信号,同时将 CurrentCount 的值减少指定数量。
TryAddCount() 增加一个 CurrentCount 的尝试。
TryAddCount(Int32) 增加指定值的 CurrentCount 的尝试。
Wait() 阻止当前线程,直到设置了 CountdownEvent 为止。
Wait(CancellationToken) 阻止当前线程,直到设置了 CountdownEvent 为止,同时观察 CancellationToken。
Wait(Int32) 阻止当前线程,直到设置了 CountdownEvent 为止,同时使用 32 位带符号整数测量超时。
Wait(Int32, CancellationToken) 阻止当前线程,直到设置了 CountdownEvent 为止,并使用 32 位带符号整数测量超时,同时观察 CancellationToken。
Wait(TimeSpan) 阻止当前线程,直到设置了 CountdownEvent 为止,同时使用 TimeSpan 测量超时。
Wait(TimeSpan, CancellationToken) 阻止当前线程,直到设置了 CountdownEvent 为止,并使用 TimeSpan 测量超时,同时观察 CancellationToken。

API 比较多,没事,我们来慢慢了解它。

示例

我们来编写一个场景代码,一个有五件事,需要完成,分别派出 5 个人去实现。

.Wait(); 用在一个线程中,这个线程将等待其它完成都完成任务后,才能继续往下执行。

Signal(); 用于工作线程中,向 CountdownEvent 对象发送信号,告知线程已经完成任务,然后 CountdownEvent.CurrentCount 将减去 1。

当计数器为 0 时,阻塞的线程将恢复执行。

代码示例如下:

    class Program
    {
        // 手头上有 5 件事
        private static CountdownEvent countd = new CountdownEvent(5);
        static void Main(string[] args)
        {
            Console.WriteLine(开始交待任务);
            // 同时叫 5 个人,去做 5 件事
            for (int i = 0; i 

示例很简单,每个线程在完成自己的任务时,需要调用 Signal() 方法,使得计数器减去1。

.Wait(); 可以等待所有的任务完成。

需要注意的是,如果不调用 Signal() 或者计数器一直不为0,那么 Wait() 将无限等待。

当然,Wait() 可以设置等待时间,

另外我们也看到了常用方法中有 AddCount()、Reset()等。

这个类的等待控制方式比较宽松,Wait() 后,到底什么时候才能执行,全凭其它线程自觉。

如果发现线程执行任务失败,我们可以不调用 Signal() 或者 使用 AddCount() 来增加次数,进行重试

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: c 多线程 完成 线程
最后更新:2021年3月15日

痴者工良

高级程序员劝退师

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

文章目录
  • 解决一个问题
  • CountdownEvent 类
    • 构造函数和方法
    • 示例

COPYRIGHT © 2022 whuanle.cn. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

粤ICP备18051778号

粤公网安备 44030902003257号