可以锁定所有键的 AsyncDuplicateLock

An AsyncDuplicateLock that can be locked on all keys

我需要一把类似于 Stephen Cleary 的回答中的锁:

但是,我还需要能够同时锁定所有键。我也在使用 Stephen Cleary's AsyncEx library,所以我想像这样将 AsyncDuplicateLock 与 AsyncReaderWriterLock 结合起来:

public sealed class AsyncDuplicateReaderWriterLock
{
    private AsyncReaderWriterLock _rwLock = new AsyncReaderWriterLock();
    private AsyncDuplicateLock _duplicateLock = new AsyncDuplicateLock();

    public IDisposable ReaderLock(object key)
    {
        return CollectionDisposable.Create(
                _rwLock.ReaderLock(),
                _duplicateLock.Lock(key)
            );
    }

    public async Task<IDisposable> ReaderLockAsync(object key)
    {
        return CollectionDisposable.Create(
            await _rwLock.ReaderLockAsync(),
            await _duplicateLock.LockAsync(key));
    }

    public IDisposable WriterLock()
    {
        return _rwLock.WriterLock();
    }

    public async Task<IDisposable> WriterLockAsync()
    {
        return await _rwLock.WriterLockAsync();
    }
}

这样我就可以用ReaderLock锁定一个key,用WriterLock锁定所有key。做对这一点很重要,所以我想确保没有办法让它死锁或锁定不正确。我对此没有足够的信心。

那么这项工作是否有效,并且是线程安全的?

感谢您的帮助!

我强烈,强烈建议你退后一步,想想你试图解决的实际问题,向其他人解释,然后问他们如何将解决并发问题。

就是说,是的,您可以(滥用)使用 reader/writer 锁来执行此操作。就个人而言,我会把锁定分开:

public IDisposable ReaderLock(object key)
{
  var rwKey = _rwLock.ReaderLock();
  var duplicateKey = _duplicateLock.Lock(key);
  return CollectionDisposable.Create(rwKey, duplicateKey);
}

// (and the same for async)

这使得代码首先采用 RWL 更加明显(为了正确,它必须这样做)。