ReaderWriterLockSlim和async \ await

我有一些ReaderWriterLockSlim问题。 我无法理解它是如何工作的。

我的代码:

  private async Task LoadIndex() { if (!File.Exists(FileName + ".index.txt")) { return; } _indexLock.EnterWriteLock();//  _index.Clear(); using (TextReader index = File.OpenText(FileName + ".index.txt")) { string s; while (null != (s = await index.ReadLineAsync())) { var ss = s.Split(':'); _index.Add(ss[0], Convert.ToInt64(ss[1])); } } _indexLock.ExitWriteLock(); } 

当我在输入写锁定时,在调试器中我可以看到_indexLock.IsWriteLockHeldtrue ,但是当执行步骤为时,我看到_indexLock.IsWriteLockHeldfalse_indexLock.ExitWriteLock抛出exceptionSynchronizationLockException并显示消息“The write锁被释放而没有被举行“。 我做错了什么?

ReaderWriterLockSlim是一个线程仿射锁类型,因此它通常不能与asyncawait一起使用。

您应该将SemaphoreSlimWaitAsync一起WaitAsync ,或者(如果您确实需要读取器/写入器锁定),请使用AsyncReaderWriterLock的AsyncReaderWriterLock或Stephen Toub的AsyncReaderWriterLock

您可以使用可靠且轻量级的SemaphoreSlim安全地模拟读取器/写入器锁定机制,并保留async / await的优点。 创建SemaphoreSlim ,为其提供相当于锁定资源以便同时读取的例程数量的可用锁数。 每个人都会像往常一样请求一把锁。 对于您的编写例程,请确保在执行此操作之前请求所有可用的锁。

这样,您的编写例程将始终单独运行,而您的读取例程可能只在它们之间共享资源。

例如,假设您有2个读取例程和1个写入例程。

 SemaphoreSlim semaphore = new SemaphoreSlim(2); async void Reader1() { await semaphore.WaitAsync(); try { // ... reading stuff ... } finally { semaphore.Release(); } } async void Reader2() { await semaphore.WaitAsync(); try { // ... reading other stuff ... } finally { semaphore.Release(); } } async void ExclusiveWriter() { // the exclusive writer must request all locks // to make sure the readers don't have any of them // (I wish we could specify the number of locks // instead of spamming multiple calls!) await semaphore.WaitAsync(); await semaphore.WaitAsync(); try { // ... writing stuff ... } finally { // release all locks here semaphore.Release(2); // (oh here we don't need multiple calls, how about that) } } 

显然,只有当您事先知道可以同时运行多少个读取例程时,此方法才有效。 不可否认,他们中的太多会让这段代码变得非常丑陋。