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

C#中通过方法锁定属性访问的线程安全实现方案问询

解决方案

要实现你需要的事务式线程安全控制,ReaderWriterLockSlim是最适合的工具——它能区分读/写锁,既保证写操作(事务期间)的排他性,又能让无冲突的读操作并发执行,同时满足"更新事务完成后才允许读取"的需求。

修改后的完整类代码

internal class Invite : IDisposable
{
    private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
    private int _State = 0;

    public int State
    {
        get
        {
            // 读取时获取读锁,写锁持有期间会阻塞等待
            _lock.EnterReadLock();
            try
            {
                return _State;
            }
            finally
            {
                // 确保锁一定会释放,避免死锁
                _lock.ExitReadLock();
            }
        }
        set
        {
            // 如果允许直接修改State(不通过EnterUpdate),这里加写锁保证线程安全
            // 若只允许在EnterUpdate事务内修改,可移除这段锁逻辑
            _lock.EnterWriteLock();
            try
            {
                _State = value;
            }
            finally
            {
                _lock.ExitWriteLock();
            }
        }
    }

    public void EnterUpdate()
    {
        // 获取排他写锁,此时所有读/写操作都会阻塞
        _lock.EnterWriteLock();
    }

    public void ExitUpdate()
    {
        // 检查并释放写锁,避免重复释放引发异常
        if (_lock.IsWriteLockHeld)
        {
            _lock.ExitWriteLock();
        }
    }

    // 释放ReaderWriterLockSlim资源
    public void Dispose()
    {
        _lock.Dispose();
    }
}

关键逻辑说明

  1. 读锁与写锁的排他性:

    • 调用EnterUpdate()后,当前线程会持有排他写锁,此时任何线程调用State的getter(读锁)或尝试获取写锁都会被阻塞,直到ExitUpdate()释放写锁。
    • 无事务时,多个线程可以同时获取读锁读取State,保证读性能。
  2. 安全使用规范:
    必须用try-finally包裹事务代码,确保锁在异常场景下也能释放:

    using var obInvite = new Invite();
    try
    {
        obInvite.EnterUpdate();
        // 执行第三方服务更新、修改State等操作
        obInvite.State = await UpdateThirdPartyService();
    }
    finally
    {
        obInvite.ExitUpdate();
    }
    
  3. 为什么之前的尝试可能失败:

    • Mutex:是跨进程锁,开销极大,且若未正确调用ReleaseMutex()会导致永久阻塞,不适合单进程内的线程同步。
    • Monitor:仅支持排他锁,无法区分读/写场景,会导致所有读操作也串行执行,性能低下;若锁对象使用不当(比如用this或值类型)也会引发问题。
    • ReaderWriterLockSlim:若之前未正确配对Enter/Exit锁(比如漏写finally释放),或错误混用读/写锁顺序,会导致死锁或锁不生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 04:50:08