寻求C#中Monitor.TryEnter的RAII包装类,避免自行实现
Monitor.TryEnter 的现成RAII包装类
在.NET 5及更高版本中,官方已经提供了System.Threading.Lock类,它原生支持RAII模式的锁管理,完全可以替代你自行实现的RAIIMonitor,无需重复造轮子。
官方Lock类的示例用法
var objToLock = new object(); using var lockHolder = objToLock.TryLock(TimeSpan.FromSeconds(2)); if (lockHolder.IsHeld) { // 执行需要加锁的操作 }
TryLock方法会返回一个LockHolder实例,它实现了IDisposable接口,在using块结束时会自动释放锁(仅当成功获取到锁时),逻辑和你设想的完全一致。
针对旧.NET版本的方案
如果是在.NET Framework等较早版本中,没有官方的Lock类,你提供的实现思路是可行的,但可以优化几个细节:
- 将
HasLock和锁对象设为只读,避免外部意外修改 - 增加入参null检查,防止
Monitor.TryEnter抛出异常 - 简化Dispose逻辑,减少不必要的判断
优化后的实现示例:
class RAIIMonitor : IDisposable { private bool _disposed = false; private readonly object _lockObj; public bool HasLock { get; } private RAIIMonitor(object lockObj, bool hasLock) { _lockObj = lockObj; HasLock = hasLock; } public static RAIIMonitor TryEnter(object lockObj, TimeSpan timeout) { if (lockObj == null) throw new ArgumentNullException(nameof(lockObj)); bool hasLock = false; Monitor.TryEnter(lockObj, timeout, ref hasLock); return new RAIIMonitor(lockObj, hasLock); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (_disposed) return; if (disposing && HasLock) { Monitor.Exit(_lockObj); } _disposed = true; } }
内容的提问来源于stack exchange,提问作者bpeikes
相关产品推荐
相关产品推荐

