传送门:异步编程系列目录……

最近在学习.NET4.5关于“并行任务”的使用。“并行任务”有自己的同步机制,没有显示给出类似如旧版本的:事件等待句柄、信号量、lock、ReaderWriterLock……等同步基元对象,但我们可以沿溪这一编程习惯,那么这系列翻译就是给“并行任务”封装同步基元对象。翻译资源来源《(译)关于Async与Await的FAQ》

1.         构建Async同步基元,Part 1 AsyncManualResetEvent

2.         构建Async同步基元,Part 2 AsyncAutoResetEvent

3.         构建Async同步基元,Part 3 AsyncCountdownEvent

4.         构建Async同步基元,Part 4 AsyncBarrier

5.         构建Async同步基元,Part 5 AsyncSemaphore

6.         构建Async同步基元,Part 6 AsyncLock

7.         构建Async同步基元,Part 7 AsyncReaderWriterLock

源码:构建Async同步基元.rar

开始:构建Async同步基元,Part 3 AsyncCountdownEvent

在我之前的两篇文章中,我已经构建了AsyncManualResetEvent 和AsyncAutoResetEvent同步基元,在这篇文章中我要创建一个简单的AsyncCountdownEvent。

CountdownEvent是这样一个事件,它允许多个等待者在接收到特定数量的信号后才完成等待。“倒计时事件”思想来自于fork/join模式(Fork/Join模式:分而治之,然后合并结果,这么一种编程模式),通常设计为:初始化一定数量的参与者,而当他们都发出事件信号时,这个倒计时从原始值变为0。当倒计时为0时CountdownEvent变成有信号状态,并且所有的等待者可以完成。

这是我们将构建的目标类型:

1
2
3
4
5
6
public class AsyncCountdownEvent
{
    public AsyncCountdownEvent(int initialCount);
    public Task WaitAsync();
    public void Signal();
}

一个倒计时事件实际是由一个手动重置事件和一个内部计数实现,所以我们的AsyncCountdownEvent将还包含两个成员:

1
2
private readonly AsyncManualResetEvent m_amre = new AsyncManualResetEvent();
private int m_count;

在类型的构造函数中进行m_count变量初始化,以提供特定数量的参与者。

1
2
3
4
5
6
public AsyncCountdownEvent(int initialCount)
{
    if (initialCount <= 0)
        throw new ArgumentOutOfRangeException("initialCount");
    m_count = initialCount;
}

对于WaitAsync()方法我们直接委托给AsyncManualResetEvent的相应方法。

1
public Task WaitAsync() { return m_amre.WaitAsync(); }

最后,我们的Signal()方法将递减m_count变量直到值为0,然后调用AsyncManualResetEvent的set()方法。

1
2
3
4
5
6
7
8
9
10
11
public void Signal()
{
    if (m_count <= 0)
        throw new InvalidOperationException();
  
    int newCount = Interlocked.Decrement(ref m_count);
    if (newCount == 0)
        m_amre.Set();
    else if (newCount < 0)
        throw new InvalidOperationException();
}

AsyncCountdownEvent类型还有一个常见的模式:用它作为一种形式的关卡|屏障,一个参与者发出到达信号并且等待其他参与者到达。为了达到此目的,我们能还可以添加一个简单的SignalAndWait()方法来实现这个常见的模式。

1
2
3
4
5
public Task SignalAndWait()
{
    Signal();
    return WaitAsync();
}

这就是本节要讲的AsyncCountdownEvent。

完整源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class AsyncCountdownEvent
{
    // 手动重置事件
    private readonly AsyncManualResetEvent m_amre = new AsyncManualResetEvent();
    // 一个内部计数
    private int m_count;
     
    public AsyncCountdownEvent(int initialCount)
    {
        if (initialCount <= 0)
            throw new ArgumentOutOfRangeException("initialCount");
        m_count = initialCount;
    }
 
    public Task WaitAsync()
    {
        return m_amre.WaitAsync();
    }
 
    public void Signal()
    {
        if (m_count <= 0)
            throw new InvalidOperationException();
 
        int newCount = Interlocked.Decrement(ref m_count);
        if (newCount == 0)
            m_amre.Set();
        else if (newCount < 0)
            throw new InvalidOperationException();
    }
 
    // 用它作为一种形式的关卡|屏障,一个参与者发出到达信号并且等待其他参与者到达。
    public Task SignalAndWait()
    {
        Signal();
        return WaitAsync();
    }
}

下一节,我将实现一个async版本的Barrier。

推荐阅读:

异步编程:同步基元对象(上)

异步编程:同步基元对象(下)

感谢你的观看……

原文:《Building Async Coordination Primitives, Part 3: AsyncCountdownEvent》

【转】3.3(译)构建Async同步基元,Part 3 AsyncCountdownEvent相关推荐

  1. 【转】3.7(译)构建Async同步基元,Part 7 AsyncReaderWriterLock

    传送门:异步编程系列目录-- 最近在学习.NET4.5关于"并行任务"的使用."并行任务"有自己的同步机制,没有显示给出类似如旧版本的:事件等待句柄.信号量.l ...

  2. 【转】3.6(译)构建Async同步基元,Part 6 AsyncLock

    传送门:异步编程系列目录-- 最近在学习.NET4.5关于"并行任务"的使用."并行任务"有自己的同步机制,没有显示给出类似如旧版本的:事件等待句柄.信号量.l ...

  3. 【转】3.5(译)构建Async同步基元,Part 5 AsyncSemaphore

    传送门:异步编程系列目录-- 最近在学习.NET4.5关于"并行任务"的使用."并行任务"有自己的同步机制,没有显示给出类似如旧版本的:事件等待句柄.信号量.l ...

  4. 【转】3.4(译)构建Async同步基元,Part 4 AsyncBarrier

    传送门:异步编程系列目录-- 最近在学习.NET4.5关于"并行任务"的使用."并行任务"有自己的同步机制,没有显示给出类似如旧版本的:事件等待句柄.信号量.l ...

  5. 【转】3.2(译)构建Async同步基元,Part 2 AsyncAutoResetEvent

    传送门:异步编程系列目录-- 最近在学习.NET4.5关于"并行任务"的使用."并行任务"有自己的同步机制,没有显示给出类似如旧版本的:事件等待句柄.信号量.l ...

  6. 【转】3.1(译)构建Async同步基元,Part 1 AsyncManualResetEvent

    传送门:异步编程系列目录-- 最近在学习.NET4.5关于"并行任务"的使用."并行任务"有自己的同步机制,没有显示给出类似如旧版本的:事件等待句柄.信号量.l ...

  7. 【转】1.4异步编程:轻量级线程同步基元对象

    开始<异步编程:同步基元对象(下)> 示例:异步编程:轻量级线程同步基元对象.rar 在<异步编程:线程同步基元对象>中我介绍了.NET4.0之前为我们提供的各种同步基元(包括 ...

  8. 【转】1.3异步编程:线程同步基元对象

    开始<异步编程:同步基元对象(上)> 示例:异步编程:线程同步基元对象.rar 如今的应用程序越来越复杂,我们常常需要多线程技术来提高我们应用程序的响应速度.每个线程都由自己的线程ID,当 ...

  9. 几何基元_.NET异步协调基元中的两种技术比较

    几何基元 Last week in my post on updating my Windows Phone 7 application to Windows 8 I shared some code ...

最新文章

  1. [快速技巧]通过命令在 Debian/Ubuntu 中设置默认浏览器
  2. centos6.5_x64远程链接输入正确的账号密码无法登陆
  3. Thymeleaf文档
  4. 刚学GDI+和.Net WinForm控件开发时做的Training Project
  5. SpringBatch批处理框架入门(二)
  6. ClickHouse【环境搭建 01】Linux环境单机版在线安装 Code:210.DB::NetException + Init script is already running 问题处理
  7. UITableViewCell的高亮和选中以及自绘分割线
  8. Mac源码安装使用OpenCV
  9. 【题解】Luogu P5294 [HNOI2019]序列
  10. Unity笔记之凤凰模拟器
  11. C++--22.特殊类的设计
  12. 数据结构(C语言)超详细视频教程
  13. 建设智慧城市,需要解决哪些问题?
  14. 数据结构作业总结_三种迷宫生成算法+三种走迷宫算法+pyqt5可视化(1)
  15. Java实现牛牛算法详解
  16. 二维码图片生成 hutool
  17. 用c语言实现简单的项目信息管理系统(单向链表实现)
  18. [Oracle]如果表存在则删除重新创建
  19. 145.如何评价个性化推荐系统的效果-2
  20. UVa 1624 打结(Knots)

热门文章

  1. Pycharm中运行Python代码的几种方式
  2. OpenCV+3计算机视觉++Python语言实现+第二版pdf
  3. Linux服务部署之NTP时间服务器
  4. angularjs中的分页指令
  5. 《C++ Primer Plus(第六版)》(25)(第十三章 类继承 笔记)
  6. SharePoint 2010 RBS 安装和配置遇到的一个问题
  7. html和css可以用在ssh里面么,在网站中使用SSH
  8. java 域的隐藏_Windows Server 2008R2\2012\2016使用域策略自定义隐藏指定驱动器
  9. vue中waiting for update signal from wds_10个vue快捷开发技巧助你成为中级前端工程师!(二)...
  10. python可以开发exe软件吗_python能开发exe软件吗