我该如何使用RWLock来实现许多读者一个作者的方案?

时间:2019-06-20 11:42:25

标签: c# .net multithreading asynchronous rwlock

我正在尝试编写一种处理某些消息的方法。它们可以读取或写入消息。允许并行读取,但是当获取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,一行Write task start,然后100行Readonly task done,然后一行Write task done,然后打印程序的其余部分

实际结果:

Readonly task start
Readonly task done

LockRecursionException4
Recursive read lock acquisitions not allowed in this mode. 

我不知道递归在这里出现的位置。我只是调用一个函数,没有任何形式的递归。我读过文章,但在这里看不到它的工作原理。

0 个答案:

没有答案