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

如何在C#中封装锁并追踪其最后一次被获取的时间?

追踪锁的最后获取时间(无需重复修改使用处)

我有一个用于同步蓝牙资源访问的锁,在10个不同位置被使用。需要追踪这个锁最后一次被获取的时间,但不想在每一处使用位置都添加重复代码。

现有代码:

private DateTime lastTimeLockAcquired;
private static object _lock = new Object();

锁的使用示例:

public void SendData1(){
   lock(_lock){
        // 业务逻辑
   }
}

public void SendData2(){
   lock(_lock){
       // 业务逻辑 
   } 
}

初步想法是封装获取和释放锁的方法,但希望更进一步,把锁和时间追踪逻辑封装到独立类中,寻求更简洁的实现。


解决方案:封装带时间追踪的自定义锁类

可以创建一个实现IDisposable接口的自定义锁类,将锁对象、时间记录逻辑完全封装,使用时通过using语句替代原有的lock语法,既保留简洁性,又自动完成时间更新和锁释放,无需在每个使用位置重复编写时间记录代码。

实现代码

public class TimedLock : IDisposable
{
    private readonly object _lockObj;
    public DateTime LastAcquiredTime { get; private set; }

    // 私有构造,通过静态方法创建实例
    private TimedLock(object lockObj)
    {
        _lockObj = lockObj;
        Monitor.Enter(_lockObj);
        LastAcquiredTime = DateTime.Now;
    }

    // 自动释放锁
    public void Dispose()
    {
        Monitor.Exit(_lockObj);
    }

    // 静态工厂方法,简化实例创建
    public static TimedLock Acquire(object lockObj)
    {
        return new TimedLock(lockObj);
    }
}

使用方式

首先定义全局共享的锁对象(确保所有方法使用同一锁):

private static readonly object _bluetoothLock = new object();

然后在各个方法中替换原lock语句:

public void SendData1()
{
    using (TimedLock.Acquire(_bluetoothLock))
    {
        // 执行蓝牙相关业务逻辑
    }
}

public void SendData2()
{
    using (TimedLock.Acquire(_bluetoothLock))
    {
        // 执行蓝牙相关业务逻辑
    }
}

如果需要获取最后一次锁的获取时间,直接通过TimedLock实例的LastAcquiredTime属性访问即可(如果需要全局共享该时间,可以将TimedLock实例设为静态)。

更彻底的封装(无需外部锁对象)

如果不想暴露锁对象,可以把锁完全封装在类内部:

public class TimedLock : IDisposable
{
    private readonly object _lockObj = new object();
    public DateTime LastAcquiredTime { get; private set; }

    private TimedLock() { }

    public void Dispose()
    {
        Monitor.Exit(_lockObj);
    }

    public static TimedLock Acquire()
    {
        var timedLock = new TimedLock();
        Monitor.Enter(timedLock._lockObj);
        timedLock.LastAcquiredTime = DateTime.Now;
        return timedLock;
    }
}

使用时只需创建全局实例:

private static readonly TimedLock _bluetoothTimedLock = TimedLock.Acquire();

public void SendData1()
{
    using (_bluetoothTimedLock)
    {
        // 业务逻辑
    }
}

内容的提问来源于stack exchange,提问作者Jai dewani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 07:27:38