You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 22:33:23