1

我正在尝试编写一种处理某些消息的方法。它们可以被读取或写入消息。允许并行读取,但是当write获得锁时,所有后续的读锁都应该等到写锁被释放。所以我认为ReaderWriterLockSlim这是我需要的。但是当我尝试实现简单的应用程序以查看它是否按预期工作时,我得到了Recursive read lock acquisitions not allowed in this mode异常。

这是我的示例来展示它的工作原理:

ReaderWriterLockSlim distributionLock = new ReaderWriterLockSlim();

async Task ExecuteReadLockTaskAsync(Func<Task> taskFunc)
{
    distributionLock.EnterReadLock();
    try
    {
        await taskFunc();
    }
    finally
    {
        if (distributionLock.IsReadLockHeld)
        {
            distributionLock.ExitReadLock();
        }
    }
}

async Task ExecuteWriteLockTaskAsync(Func<Task> taskFunc)
{
    distributionLock.EnterWriteLock();
    try
    {
        await taskFunc();
    }
    finally
    {
        if (distributionLock.IsWriteLockHeld)
        {
            distributionLock.ExitWriteLock();
        }
    }
}

Task ProcessAsync(bool flag)
{
    switch (flag)
    {
        case false:
            return ExecuteReadLockTaskAsync(() =>
            {
                Console.WriteLine("Readonly task start");
                return Task.Delay(1000).ContinueWith(t => Console.WriteLine("Readonly task done"));
            });
        case true:
            return ExecuteWriteLockTaskAsync(() =>
            {
                Console.WriteLine("Write task start");
                return Task.Delay(3000).ContinueWith(t => Console.WriteLine("Write task done"));
            });
        default:
            throw new InvalidOperationException($"Unknown message typex");
    }
}

var tasks=  new List<Task>();
for (int i = 0; i < 100; i++)
{
    tasks.Add(ProcessAsync(false));
}
tasks.Add(ProcessAsync(true));

for (int i = 0; i < 100; i++)
{
    tasks.Add(ProcessAsync(false));
}

await Task.WhenAll(tasks);

预期结果: 100 行Readonly task start, 1 行Write task start, 然后 100 行Readonly task done, 然后 1 行Write task done, 然后程序的其余部分打印。

实际结果:

Readonly task start
Readonly task done

LockRecursionException4
Recursive read lock acquisitions not allowed in this mode. 

我不明白递归出现在哪里。我只是调用一个函数,没有任何递归。我阅读了文章,但我看不到它在这里是如何工作的。

4

0 回答 0