C# 信号锁SemaphoreSlim

关于锁,我们经常会使用lock object对象,进行资源访问的限制。

但,lock是有限制的,无法添加异步方法。编译器会报错。

下面推荐另一个类SemaphoreSlim,这是信号量的一个使用类。先看下面的使用:

 1     private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
 2     {
 3         var tasks = new List<Task>();
 4         for (int i = 0; i < 10; i++)
 5         {
 6             var message = $"message{i}";
 7             tasks.Add(Task.Run(async () =>
 8             {
 9                await LockWithSemaphore(message);
10             }));
11         }
12         await Task.WhenAll(tasks);
13     }
14     private SemaphoreSlim _asyncLock = new SemaphoreSlim(1);
15     async Task LockWithSemaphore(string title)
16     {
17         Console.WriteLine($"{title} waiting for lock");
18         await _asyncLock.WaitAsync();
19 
20         Console.WriteLine($"{title} starting");
21         await Task.Delay(200);
22         Console.WriteLine($"{title} ending");
23 
24         _asyncLock.Release();
25     }

输出结果:

从控制台结果可以看出,SemaphoreSlim 完美的完成了异步场景下的锁操作,严格的保持了并发操作的互斥。

SemaphoreSlim类,从源码来看,内部其实是使用了ManualResetEvent:

 

关于信号锁,常用的有AutoResetEvent和ManualResetEvent,在线程同异步处理场景下比较常见。

SemaphoreSlim,能做的事还有很多,比如:

1. 下载并发时,限制下载并行数量为5个。我们就可以通过设置SemaphoreSlim为5来实现。

2. 访问数据库、或者硬件设备时,需要限制访问数量为1。

 

posted @ 2022-06-10 01:08  唐宋元明清2188  阅读(494)  评论(1编辑  收藏  举报