看Elsa-core源代码中看到的,Elsa-core中所有保存数据的方法似乎使用同一个Save方法 。如下图:
文章插图
那么为什么要使用这玩意,我还是头一次见这玩意
文章插图
????
好吧,我承认我自己菜 。我自个儿也该保持谦虚态度学习学习了 。
先看下这个SemaphoreSlim类的描述
文章插图
(我买的正版Resharp 2022)反编译代码如上图 。
翻译过来就是 “限制当前访问资源或池中资源的线程数” , 真的是这样的吗? 试一试...
我的代码仓库 https://github.com/qiqiqiyaya/Learning-Case/tree/main/SemaphoreSlim ,测试例子 。
例一在B乎中看到一篇文章 , 链接地址 https://zhuanlan.zhihu.com/p/158777952
我copy他的例子测试了下,如下图:
// 现在有10个人要过桥// 但是一座桥上只能承受5个人,再多桥就会塌static void SemaphoreTest(){var semaphore = new SemaphoreSlim(5);for (int i = 1; i <= 10; i++){Thread.Sleep(100); // 排队上桥var index = i; // 定义index 避免出现闭包的问题Task.Run(() =>{semaphore.Wait();try{Console.WriteLine($"第{index}个人正在过桥 。");Thread.Sleep(5000); // 模拟过桥需要花费的时间}finally{Console.WriteLine($"第{index}个人已经过桥 。");semaphore.Release();}});}}
文章插图
运行结果,与B乎上作者的结果一样 。
这里有个问题,该作者使用Task.Run 然后在其中添加了 Thread.Sleep(5000); , 这会阻塞当前的线程,导致执行 Task 任务的“任务调度器”开启了 10个线程 。
关于什么是 Task ,理解 Task , 请阅读大佬的文章,非常Nice链接 https://www.cnblogs.com/artech/p/task_scheduling.html
列二,如果在异步Async/Await中是什么情况呢?static void SemaphoreTest1(){var semaphore = new SemaphoreSlim(5);for (int i = 1; i <= 10; i++){Thread.Sleep(100); // 排队上桥var index = i; // 定义index 避免出现闭包的问题Task.Run(async () =>{Console.WriteLine($"第{index}个人已抵达桥边上 。线程Id" + Thread.CurrentThread.ManagedThreadId);semaphore.Wait();try{Console.WriteLine($"第{index}个人正在过桥 。线程Id" + Thread.CurrentThread.ManagedThreadId);//Thread.Sleep(5000); // 模拟过桥需要花费的时间await Task.Delay(5000);}finally{Console.WriteLine($"第{index}个人已经过桥 。线程Id" + Thread.CurrentThread.ManagedThreadId);semaphore.Release();}});}}将 Thread.Sleep(5000); 换成了 await Task.Delay(5000); 使用 async/await。结果如下:
文章插图
从结果上看,例如:第1个人 线程Id 3 上桥,在执行 await Task.Delay(5000); (模拟过桥需要花费的时间)后,线程Id变成了 12。这是执行 Task 的任务调度器(Task默认调度器是线程池)作用的效果 。这不是本次随笔的重点 。
再次强调关于理解Task,请参考 https://www.cnblogs.com/artech/p/task_scheduling.html 。
再次强调Task与线程Thread是两个东西,Task可以理解为一个任务,那么这个任务由Thread去执行,至于由哪一个Thread 去执行,这就由 “任务调度器” 去决定了 。
从结果上看,执行了五个Task之后,就阻止后续Task再往下执行代码了 。
列二中使用了 semaphore.Wait(); 同步阻塞,导致后续Task中使用一个之前空闲的Id为3的线程 (Id为3的线程执行到 await Task.Delay(5000) 后阻塞了,该线程被调度器拿去执行新的Task任务),并创建了另外4个新的执行Task的线程 。
结论:1.SemaphoreSlim会限制访问资源的线程数
2.在异步async/await情况下,SemaphoreSlim会限制正在执行访问资源的Task的数量
例三static void SemaphoreTest2(){var semaphore = new SemaphoreSlim(5);for (int i = 1; i <= 10; i++){Thread.Sleep(100); // 排队上桥var index = i; // 定义index 避免出现闭包的问题Task.Run(async () =>{Console.WriteLine($"第{index}个人已抵达桥边上 。线程Id" + Thread.CurrentThread.ManagedThreadId);await semaphore.WaitAsync();try{Console.WriteLine($"第{index}个人正在过桥 。线程Id" + Thread.CurrentThread.ManagedThreadId);await Task.Delay(5000);// 模拟过桥需要花费的时间}finally{Console.WriteLine($"第{index}个人已经过桥 。线程Id" + Thread.CurrentThread.ManagedThreadId);semaphore.Release();}});}}执行结果
文章插图
推荐阅读
- 迪奥720和840哪个好看_迪奥720和840试色对比
- 【ASP.NET Core】MVC控制器的各种自定义:应用程序约定的接口与模型
- “黑绷带的力量” 首先,它有一个奇怪的名字,叫“黑绷带” 其次,在看产品介绍之初,它是一款晚霜。
- 纪梵希n37和兰蔻505哪个好看?哪个值得买?
- 中 学习ASP.NET Core Blazor编程系列十——路由
- 发布 .NET 7 MAUI / MAUI Blazor 应用到 Windows 应用商店
- 花西子同心锁口红m211好看吗_花西子m211朱砂锁试色
- 如何才能画出一对好看的翅膀我没有什么画画功底的
- 天使翅膀怎么画(翅膀怎么画简单好看)
- 翅膀怎么画好看又简单(画翅膀的三种方法)