在锁中使用异步方法的最佳实践是什么

syb*_*bil 5 c# locking async-await .net-core

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

\n\n

但众所周知,异步方法在普通锁中无法正常工作,因为普通锁是相对于线程而言的。

\n\n

例如\xef\xbc\x8c在MemoryCache中使用ReadWriteLocker。当MemoryCache丢失时\xef\xbc\x8c我需要从数据库读取数据。\n我现在知道2种方法来解决这个问题:

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

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

\n

ror*_*.ap 6

lock只是监视器的语法糖,它一次只允许一个线程进入,因此它不能与 async/await 一起使用。

另一方面,信号量可以安全地协调多个线程之间对共享资源的访问。你可以用 做你需要做的事情SemaphoreSlim,就像这样。首先在字段或属性中声明一个信号量,可以从任何需要线程保护的地方访问该信号量:

public readonly SemaphoreSlim _mySemaphoreSlim = new SemaphoreSlim(1, 1);
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

await _mySemaphoreSlim.WaitAsync(cancellationToken);
// Do whatever other sync or async operations you need.
_mySemaphoreSlim.Release();
Run Code Online (Sandbox Code Playgroud)

  • 您有任何文档表明它是信号量的语法糖吗?据我所知,它实际上是“Monitor”类的语法糖,它使用分配给所有引用类型的一些额外内存来进行锁管理。 (5认同)