C# 我如何使用RWLock实现多读一写场景?

C# 我如何使用RWLock实现多读一写场景?,c#,.net,multithreading,asynchronous,rwlock,C#,.net,Multithreading,Asynchronous,Rwlock,我正在尝试编写一个处理一些消息的方法。它们可以读或写消息。允许并行读取,但当获得writelock时,所有后续读取锁应等待直到释放写入锁。所以我认为我需要的是ReaderWriterLockSlim。但当我试图实现一个简单的应用程序,看看它是否能像预期的那样工作时,我得到了在这种模式下不允许的递归读取锁获取异常 下面是我的示例,展示了它的工作原理: ReaderWriterLockSlim distributionLock=new ReaderWriterLockSlim(); 异步任务执行器R

我正在尝试编写一个处理一些消息的方法。它们可以读或写消息。允许并行读取,但当获得
write
lock时,所有后续读取锁应等待直到释放写入锁。所以我认为我需要的是
ReaderWriterLockSlim
。但当我试图实现一个简单的应用程序,看看它是否能像预期的那样工作时,我得到了在这种模式下不允许的
递归读取锁获取
异常

下面是我的示例,展示了它的工作原理:

ReaderWriterLockSlim distributionLock=new ReaderWriterLockSlim();
异步任务执行器ReadLockTaskAsync(Func taskFunc)
{
distributionLock.EnterReadLock();
尝试
{
等待taskFunc();
}
最后
{
if(分配锁。ISREADLOCKHOLD)
{
distributionLock.ExitReadLock();
}
}
}
异步任务执行器WriteLockTaskAsync(Func taskFunc)
{
distributionLock.EnterWriteLock();
尝试
{
等待taskFunc();
}
最后
{
if(distributionLock.isWriteLockHold)
{
distributionLock.ExitWriteLock();
}
}
}
任务进程异步(bool标志)
{
开关(标志)
{
案例错误:
返回ExecuteReadLockTaskAsync(()=>
{
Console.WriteLine(“只读任务启动”);
return Task.Delay(1000).ContinueWith(t=>Console.WriteLine(“只读任务完成”);
});
大小写正确:
返回ExecuteWriteLockTaskAsync(()=>
{
Console.WriteLine(“写入任务启动”);
return Task.Delay(3000).ContinueWith(t=>Console.WriteLine(“Write Task done”);
});
违约:
抛出新的InvalidOperationException($“未知消息类型X”);
}
}
var tasks=新列表();
对于(int i=0;i<100;i++)
{
添加(ProcessAsync(false));
}
添加(ProcessAsync(true));
对于(int i=0;i<100;i++)
{
添加(ProcessAsync(false));
}
等待任务。何时(任务);
预期结果:100行
只读任务开始
,一行
写入任务开始
,然后100行
只读任务完成
,然后一行
写入任务完成
,然后打印其余程序

实际结果:

Readonly task start
Readonly task done

LockRecursionException4
Recursive read lock acquisitions not allowed in this mode. 

我不明白这里出现递归的地方。我只调用一个函数,没有任何递归。我读过文章,但不知道它在这里是如何工作的。

可能重复的。(答案是“不”。)我的错误不同。不过,这个链接很有用,谢谢。不同的错误,但根本原因相同——如果
wait
从启动时就在不同的线程上结束,锁就不会被释放(因为它不认为它持有锁),当任务最终在仍然持有锁的线程上运行时,你会得到这个错误。是的,我明白了。那么它实际上是一个复制品。但我看不到任何答案,我该如何效仿才能让它发挥作用。也许我应该改变问题的主题?Stephen Cleary的答案链接到他的库,其中有一个
AsyncReaderWriterLock
。可能是的副本。(答案是“不”。)我的错误不同。不过,这个链接很有用,谢谢。不同的错误,但根本原因相同——如果
wait
从启动时就在不同的线程上结束,锁就不会被释放(因为它不认为它持有锁),当任务最终在仍然持有锁的线程上运行时,你会得到这个错误。是的,我明白了。那么它实际上是一个复制品。但我看不到任何答案,我该如何效仿才能让它发挥作用。也许我应该改变问题的主题?Stephen Cleary的答案链接到他的库,其中有一个
AsyncReaderWriterLock