C# 信号锁SemaphoreSlim

2023-07-11,

关于锁,我们经常会使用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。

C# 信号锁SemaphoreSlim的相关教程结束。

《C# 信号锁SemaphoreSlim.doc》

下载本文的Word格式文档,以方便收藏与打印。