在C#中,如何知道线程是否正在等待进入ReaderWriterLockSlim的写锁定

本文关键字:在等待 ReaderWriterLockSlim 锁定 写锁 是否 线程 何知道 | 更新日期: 2023-09-27 18:24:30

我正在尝试为列表实现ReaderWriterLockSlim。我希望每个线程都能同时从列表中读取,但只允许一个线程"等待"写入锁定。如果一个线程试图获得写锁的控制权,而另一个线程已经在写或等待写,我希望它不要等待锁。我已经找到了TryEnterReadLock(Int32)方法,但据我所知,它只会等到调用线程能够控制写锁或达到超时。我会在超时为"0"的情况下尝试,但是,我认为这不会起作用,因为如果其他线程拥有读锁,它会在访问写锁之前超时。我知道我可以用一个变量来表示线程是否正在写入或等待写入,但我想知道是否有更专业的方法来实现这一点(我不想创建另一个变量,从而为它创建互斥锁)。

在C#中,如何知道线程是否正在等待进入ReaderWriterLockSlim的写锁定

将逻辑进一步向后移动,在超时为0的读卡器上使用TryEnterUpgradeableReadLock,然后一个读卡器成为您的编写器,等待其他读卡器完成。

public void YourFunction()
{
    bool enteredUpgLock = false;
    bool enteredWriteLock = false;
    try
    {
        //Preemptively take a upgradeable read lock, only one thread can do this.
        enteredUpgLock = _readerWriterLock.TryEnterUpgradeableReadLock(0);
        try
        {
            //If we don't have the upgradeable lock take a normal read lock.
            if (!enteredUpgLock)
            {
                _readerWriterLock.EnterReadLock();
            }
            DoReadWork();
        }
        finally
        {
            //Release the read lock if we had it.
            if(!enteredUpgLock)
                _readerWriterLock.ExitReadLock();
        }
        try
        {
            if (enteredUpgLock)
            {
                //We held the upgradeable lock, wait forever till we can take it.
                _readerWriterLock.EnterWriteLock();
                enteredWriteLock = true;
            }
            else
            {
                //We did not have the upgrade lock, try to take the write lock but if we can't bail out.
                enteredWriteLock = _readerWriterLock.TryEnterWriteLock(0);
                if(!enteredWriteLock)
                    return;
            }
            DoWriteWork();
        }
        finally 
        {
            if(enteredWriteLock)
                _readerWriterLock.ExitWriteLock();
        }
    }
    finally 
    {
        //If we had the upgradeable lock, release it.
        if (enteredUpgLock)
        {
            _readerWriterLock.ExitUpgradeableReadLock();
        }
    }
}