前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >2019-12-1-使用SemaphoreSlim实现异步等待

2019-12-1-使用SemaphoreSlim实现异步等待

作者头像
黄腾霄
发布于 2020-06-10 07:06:29
发布于 2020-06-10 07:06:29
1.9K00
代码可运行
举报
文章被收录于专栏:黄腾霄的博客黄腾霄的博客
运行总次数:0
代码可运行

Semaphore大家应该都很熟悉,一个能够指定最大并发个数的同步锁。

实际上.NET还有一个轻量级的信号量实现SemaphoreSlim,其不但能够更加高效的实现信号量的功能,还提供了一个异步等待的API


我们首先回忆下SemaphoreSlim同步等待时的情况。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    class Program
    {
        private static SemaphoreSlim semaphore;
        static void Main(string[] args)
        {
            semaphore = new SemaphoreSlim(1, 1);
            var tasks = new Task[2];

            for (int i = 0; i <= 1; i++)
            {
                tasks[i] = Task.Run(() =>
                {
                    Console.WriteLine("Task {0}等待信号量",
                        Task.CurrentId);
                    semaphore.Wait();
                    Console.WriteLine("Task {0} 获得信号量.", Task.CurrentId);
                    //模拟做事情况
                    Thread.Sleep(1000);

                    Console.WriteLine("Task {0} 释放信号量; 释放前数目: {1}.",
                        Task.CurrentId, semaphore.Release());
                });
            }

            // 等待task执行完成.
            Task.WaitAll(tasks);
            Console.ReadLine();
        }
    }

如上所示的代码中,SemaphoreSlim的初始信号数是1,且同时只能有一个线程获得锁。

此时我们的代码会依次执行。

但是此时task1和task2 的线程是阻塞的。那么在UI线程上使用,尤其是WPF这种单线程应用来说,几乎是不可行的。

此时我们就可以使用今天的主角WaitAsync

我们稍稍修改下代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    class Program
    {
        private static SemaphoreSlim semaphore;

        static void Main(string[] args)
        {
            semaphore = new SemaphoreSlim(, );
            var tasks = new Task[];

            for (int i = ; i <= ; i++)
            {
                tasks[i] = Task.Run(async () =>
                {
                    var currentId = Task.CurrentId;
                    Console.WriteLine("Task {0}等待信号量",
                        currentId);
                    Foo(currentId);
                    Console.WriteLine("Task {0} 执行非同步区代码.", currentId);
                    Thread.Sleep();
                    Console.WriteLine("Task {0} 非同步区代码执行完成.", currentId);
                });
            }

            // 等待task执行完成.
            Task.WaitAll(tasks);
            Console.ReadLine();
        }

        public static async Task Foo(int? id)
        {
            var currentId = id;
            await semaphore.WaitAsync();
            Console.WriteLine("Task {0} 获得信号量.", currentId);
            //模拟做事情况
            Console.WriteLine("Task {0} 执行同步区代码.", currentId);
            Thread.Sleep();
            Console.WriteLine("Task {0} 同步区代码执行完成.", currentId);
            Console.WriteLine("Task {0} 释放信号量; 释放前数目: {1}.",
                currentId, semaphore.Release());
        }
    }

我们将同步区执行的代码抽取到方法Foo中,而内部调用WaitAsync

结果如下所示

我们看到task3在没有获得同步锁的情况下WaitAsync直接返回线程控制权,所以task3线程没有被阻塞能够优先执行非同步区代码。而在获得信号量之后,继续执行同步区代码。


参考文档:


本文会经常更新,请阅读原文: https://xinyuehtx.github.io/post/%E4%BD%BF%E7%94%A8SemaphoreSlim%E5%AE%9E%E7%8E%B0%E5%BC%82%E6%AD%A5%E7%AD%89%E5%BE%85.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-12-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Go+数组
    Go+提供了一种长度固定的数据结构结构,他就是数组,他可以用于存放多个相同类型的数据,比如我们要存放100个同学的姓名,我们需要name1、name2、name3…这样来命名,略显繁琐,遇到这种情况,我们可以直接使用数组来进行存储。我们再根据索引(下标)去取值,他的下标是从0开始的,第一个下标是1,初学者可能不是很习惯这种方式。
上分如喝水
2021/12/09
2830
javascript对象数组内元素排序
注意:想往后排的,后面的-前面的  a.age - b.age ,如果是从小到大排序,大的-小的
唯一Chat
2022/10/28
2.1K0
JavaScript比较两个数组是否相等(多选题答案判断)
如果使用了组件库,比如 element-ui 的 checkout 组件,选择顺序不同,得到的数组顺序就会不同。
德顺
2021/05/14
1.6K0
5 个 JS 数组技巧可提高你的开发技能
在前端开发中,数组是经常会被用到的数组结构,今天,介绍 5 个处理数组技巧,希望能带给你们一些 启发和帮助。废话不多说,让我们开始吧。
前端小智@大迁世界
2020/08/06
1.3K0
通过事例重温一下常见的 JS 中 15 种数组操作(备忘清单)
数组是 JS 中广泛使用的数据结构。数组对象提供了大量有用的方法,如array. forEach()、array.map()等来操作数组。
前端达人
2019/12/24
1.2K0
数组、字符串方法大全
delete:删除键值对的方式也可以删除数组中的对应项,不会改变数组中原有项的索引
星辰大海c
2023/11/20
2270
数组、字符串方法大全
JavaScript中常用的数组方法总结
forEach()函数是JavaScript数组提供的一个用于遍历数组的方法。它接受一个回调函数作为参数,并且对数组中的每个元素依次调用该回调函数。
九仞山
2023/10/14
3720
Hash 与 Hash表 与 HashCode、HashMap 数据结构、HashMap 的容量
在 JDK1.7 当中 HashTable 数据结构为 数组 + 链表,假定现在有一个 HashMap 内容如下。
杨不易呀
2023/11/14
4710
Hash 与 Hash表 与 HashCode、HashMap 数据结构、HashMap 的容量
大数据ClickHouse(八):MergeTree系列表引擎之MergeTree(重点掌握)
在所有的表引擎中,最为核心的当属MergeTree系列表引擎,这些表引擎拥有最为强大的性能和最广泛的使用场合。对于非MergeTree系列的其他引擎而言,主要用于特殊用途,场景相对有限。而MergeTree系列表引擎是官方主推的存储引擎,有主键索引、数据分区、数据副本、数据采样、删除和修改等功能,支持几乎所有ClickHouse核心功能。
Lansonli
2022/08/17
8680
大数据ClickHouse(八):MergeTree系列表引擎之MergeTree(重点掌握)
重读《学习JavaScript数据结构与算法-第三版》- 第3章 数组(二)
读《学习JavaScript数据结构与算法》- 第3章 数组,本小节将继续为各位小伙伴分享数组的相关知识:ES6数组的新功能。
胡哥有话说
2019/08/20
5360
js数组常用方法「建议收藏」
请注意,上面的代码没有按照数值的大小对数字进行排序,是按照字符编码的顺序进行排序,要实现这一点,就必须使用一个排序函数:
全栈程序员站长
2022/08/30
2.5K0
JS快速删除数组中的指定元素
findIndex() 方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回 -1。
德顺
2022/06/27
7.5K0
(一)数组常用API
# 一下呢是我自己整理的一些数组常用的API # 一、向数组末尾添加一个元素 push() // 向数组末尾添加一个元素 pop() // 删除数组最后一个元素 # 二、向数组开头添加一个元素 unshift() // 向数组开头添加一个元素 shift() // 删除数组开头第一个元素 # 三、对两个数组进行拼接 concat() // 对两个数组进行拼接 语法:arr.concat(['你', '好'], ['欢', '迎']) 也可以使用扩展
老怪兽
2023/02/10
2850
【JS】297-[译]正确使用 sort() 方法
在过去的几个星期里,我们在不同的团队中看到,一般来说都没有使用 Array.prototype.sort()的习惯,并且不知道这种方法是如何工作的。今天我们将尝试简要描述它是如何工作的 .sort(),揭示它的一些秘密。
pingan8787
2019/07/24
1.6K0
学习R语言里的排序函数
我们的生信入门班和数据挖掘线上直播课程已经有了三年多的历史,培养了一波又一波优秀的生信人才。新一期的生信入门班学员热情高涨,他们富有探索精神,又乐于助人,这是一个在帮助别人的过程中自己也获得进步的例子,令我们非常开心。
生信技能树
2022/06/08
1.1K0
学习R语言里的排序函数
大数据之脚踏实地学15--Scala的数组操作
Scala中的数组是一种非常重要的数据结构,它是用来存储同类型元素的容器,除此Scala还有其他存储数据的容器,例如元组、列表、映射等。在本期的内容分享中,我们将针对数组作基本的介绍,内容包含:
1480
2019/05/21
9290
JavaScript专题(二)数组去重,会就要会的理直气壮
如果数组中有NaN,你又正好需要判断数组是否有存在NaN,这时你使用indexOf是无法判断的,你必须使用includes这个方法。
全栈程序员站长
2022/07/04
4080
Javascript中的数组对象排序(转载)
js中用方法sort()为数组排序。sort()方法有一个可选参数,是用来确定元素顺序的函数。如果这个参数被省略,那么数组中的元素将按照ASCII字符顺序进行排序。如:
李维亮
2021/07/08
9K0
《现代Javascript高级教程》JavaScript数组
在JavaScript中,数组(Array)是一种重要且广泛应用的数据结构,用于存储和操作一组有序的数据。JavaScript提供了丰富的数组方法和属性,使我们能够方便地对数组进行增删改查等操作。本文将详细介绍JavaScript数组的方法API、属性,并探讨如何模拟实现数组的API。此外,还将介绍数组的应用场景,帮助读者更好地理解和应用数组。
linwu
2023/07/31
2320
JS 中创建自定义排序方法
一般情况咱们排序大都按数字或字母顺序,但也有一些情况下,咱们可能需要自定义排序顺序。
前端小智@大迁世界
2019/08/20
1.6K0
JS 中创建自定义排序方法
相关推荐
Go+数组
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档