ReaderWriterLockSlim 是 C# 中适用于“多读少写”场景的高效读写锁,支持超时、取消和递归控制;需成对调用 Enter/ExitReadLock 或 Enter/ExitWriteLock,推荐 try/finally 保障释放,禁用递归与合理超时可提升安全性与性能。

ReaderWriterLockSlim 是 C# 中高效、轻量的读写锁实现,适合“多读少写”场景,能显著提升并发性能。它比传统的 lock 或 Monitor 更灵活,允许多个线程同时读,但写操作独占,且支持超时、取消和递归控制(可禁用)。
基本用法:读锁与写锁的正确加解锁
必须成对调用 EnterReadLock/ExitReadLock 或 EnterWriteLock/ExitWriteLock,推荐用 try/finally 保证释放,避免死锁。
- 读操作:多个线程可同时进入,调用
EnterReadLock()→ 访问共享资源 → 必须ExitReadLock() - 写操作:互斥独占,调用
EnterWriteLock()→ 修改共享资源 → 必须ExitWriteLock() - 不要混用:不能在持有读锁时直接升级为写锁(会死锁),需先释放读锁再申请写锁
安全写法示例:带超时和异常防护
实际项目中建议启用超时机制,防止无限等待;并始终在 finally 块中释放锁:
private readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();public string GetData() { _rwLock.EnterReadLock(); try { return _sharedData; } finally { _rwLock.ExitReadLock(); } }
public void UpdateData(string value) { if (_rwLock.TryEnterWriteLock(1000)) // 等待1秒,超时返回false { try { _sharedData = value; } finally { _rwLock.ExitWriteLock(); } } else { throw new TimeoutException("获取写锁超时"); } }
进阶控制:禁用递归、设置公平模式、响应取消
ReaderWriterLockSlim 构造时可传入参数调整行为:
- 禁用递归:
new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion),避免同一线程重复加锁导致逻辑混乱 - 启用公平模式:
new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion, LockRecursionPolicy.NoRecursion)(注意:.NET 6+ 支持new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion) { UseSpinWait = false }配合公平队列,但真正公平需手动管理)——更准确地说,它本身不提供严格公平,但可通过TryEnter*+ 重试 + 取消令牌模拟 - 配合
CancellationToken:使用TryEnterReadLock(Int32, CancellationToken)等重载,实现可取消的等待
注意事项与常见坑
几个容易忽略却关键的细节:
- 务必调用
Dispose()释放底层内核资源(尤其长期存活对象),建议封装为IDisposable类型或在using中创建(但注意:它不是设计为短生命周期对象,通常作为字段长期持有) - 不要在锁内调用未知外部方法(如事件、虚方法、LINQ 查询),可能引发死锁或延长锁持有时间
- 读锁下禁止修改被保护的数据,否则破坏线程安全;写锁是唯一允许修改的时机
- 嵌套锁顺序要一致(如先读再写,所有线程都按此顺序),否则易引发死锁
基本上就这些。用好 ReaderWriterLockSlim 的关键是理解“读共享、写独占”的模型,配合适当的超时和异常防护,就能在高并发读场景下兼顾安全与性能。









