C#多互斥替代单一lock:实现代码支持4-5用户并发执行
用SemaphoreSlim替代单一Lock实现可控并发(4-5用户同时执行)
嘿,这个需求其实不用手动维护多个lock对象那么麻烦,.NET里的SemaphoreSlim就是专门干这个事儿的——它能精准控制同时执行代码块的线程/用户数量,完全符合你要4-5个并发的要求,比自己折腾多个锁靠谱多了!
为什么不推荐手动维护多个Lock?
手动创建多个私有对象然后轮询分配,不仅代码冗余,还容易出现锁分配不均、异常下锁泄露的问题,维护成本高。而SemaphoreSlim是官方提供的并发控制工具,已经帮你处理了这些细节。
改造步骤和代码示例
1. 定义全局的SemaphoreSlim实例
首先在你的类里声明一个静态的SemaphoreSlim,指定最大并发数(比如5):
private static readonly SemaphoreSlim _concurrencySemaphore = new SemaphoreSlim(initialCount: 5, maxCount: 5);
initialCount:一开始允许同时进入的数量,这里和最大数保持一致就行maxCount:就是你要限制的最大并发数(4或5,按需调整)
2. 改造原有Lock代码块
把原来的lock(_privateStaticObject)替换成信号量的Wait/WaitAsync + try-finally结构:
同步代码场景:
// 原来的单lock代码 // lock(_privateStaticObject) // { // // 你的业务代码 // } // 改造后的可控并发代码 _concurrencySemaphore.Wait(); // 等待获取信号量,没有空闲名额就阻塞 try { // 你的业务代码——现在最多5个用户/线程同时执行这里 } finally { _concurrencySemaphore.Release(); // 不管有没有异常,都要释放信号量,还给"名额" }
异步代码场景(如果用async/await):
如果你的业务代码是异步的,记得用WaitAsync()避免阻塞线程:
await _concurrencySemaphore.WaitAsync(); try { // 你的异步业务代码,比如 await SomeAsyncOperation(); } finally { _concurrencySemaphore.Release(); }
关键注意事项
- 一定要用
try-finally包裹业务代码:哪怕业务代码抛出异常,也能保证信号量被释放,不会出现"名额被占死"的情况 - 如果是Web应用或者多实例场景:如果你的服务部署了多个实例,
SemaphoreSlim只能控制单个实例内的并发。要是需要跨实例的全局并发控制,就得用分布式锁(比如基于内存数据库实现),不过看你的需求应该是单实例内的控制,这个方案就够用了 - 调整并发数:直接修改
SemaphoreSlim构造函数的maxCount参数就行,非常灵活
内容的提问来源于stack exchange,提问作者Imran Qadir Baksh - Baloch
相关产品推荐
相关产品推荐

