【问题标题】:what is the best practice using async method in lock在锁定中使用异步方法的最佳实践是什么
【发布时间】:2020-02-18 21:51:57
【问题描述】:

在 .Net Core 中,许多 I/O 方法都有异步版本,微软建议我们使用它们以获得更好的性能。

但是我们知道,异步方法不能在普通锁中正常工作,因为普通锁是相对于线程而言的。

例如,在 MemoryCache 中使用 ReadWriteLocker。当 MemoryCache 缺失时,我需要从数据库中读取数据。 我现在知道解决这个问题的两种方法:

  1. 将异步数据库查询方法转换为同步,例如“Wait”或“.Result”。
  2. 使用特殊的锁,比如redis锁或者一些非官方的AsyncReaderWriteLocker。(我找到了一个,但是我还没有阅读它的代码,所以我不知道它的细节,成本或新的bug)

回到标题,当我必须在锁定中使用异步方法时,最好的方法是什么?我需要一些建议。 非常感谢您阅读我蹩脚的英语。

【问题讨论】:

  • 你可以使用SemaphoreSlim,它有一个WaitAsync方法
  • 我知道如何使用 SemaphoreSlim 代替简单的锁,但是代替 ReadWriteLocker 很难。
  • 是的,不幸的是没有内置的异步读/写锁。
  • 我们一直在使用来自Stephen Cleary's AsyncEx libraryAsyncReaderWriterLock 并取得了巨大的成功。
  • 谢谢你的回答,我会阅读AsyncReaderWriteLocker的代码。但是不知道有没有更好的方法来解决这个问题。

标签: c# .net-core async-await locking


【解决方案1】:

lock 只是信号量的语法糖。你可以用SemaphoreSlim 做你需要的事情,就像这样。首先在需要线程保护的任何地方都可以访问的字段或属性中声明一个信号量:

public readonly SemaphoreSlim _mySemaphoreSlim = new SemaphoreSlim(1, 1);

然后像这样使用它:

await _mySemaphoreSlim.WaitAsync(cancellationToken);
// Do whatever other sync or async operations you need.
_initializationSemaphoreSlim.Release();

【讨论】:

  • 谢谢解答,我知道SemaphoreSlim的基本用法,但是当我需要一个ReadWriteLocker的时候,用SemaphoreSlim写一个AsyncReadWriteLocker是很困难的。所以想知道有没有更好的方法来解决这个问题。
  • 你有任何文件证明它是信号量的语法糖吗?据我所知,它实际上是 Monitor 类的语法糖,它使用分配给所有引用类型的一些额外内存来进行锁管理。
猜你喜欢
  • 1970-01-01
  • 2018-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-05
相关资源
最近更新 更多