用于多种方法配置的异步锁
本文关键字:异步 配置 方法 用于 | 更新日期: 2023-09-27 18:36:08
我需要实现的是:
- 当 MasterAsync 正在执行时,HumbleSlave1Async 和 HumbleSlave2Async 不能执行。
- 反之亦然 - 当一个或两个从属服务器正在执行时,主异步不能。
- 困难的部分 - 奴隶不能互相阻挡。
(链接到使用的 AsyncLock)。
private async Task MasterAsync()
{
using (await _asyncLock.LockAsync())
{
await Task.Delay(2000);
}
}
private async Task HumbleSlave1Async()
{
using (await _asyncLock.LockAsync())
{
await Task.Delay(5000);
}
}
private async Task HumbleSlave2Async()
{
using (await _asyncLock.LockAsync())
{
await Task.Delay(5000);
}
}
我不确定如何解决它,正在考虑在 MasterAsync 中为每个从站使用两个不同的锁,但随后一个锁会在另一个锁中:
private async Task MasterAsync()
{
using (await _asyncLock1.LockAsync())
{
using (await _asyncLock2.LockAsync())
{
await Task.Delay(2000);
}
}
}
private async Task HumbleSlave1Async()
{
using (await _asyncLock1.LockAsync())
{
await Task.Delay(5000);
}
}
private async Task HumbleSlave2Async()
{
using (await _asyncLock2.LockAsync())
{
await Task.Delay(5000);
}
}
它有意义吗,它是否安全(死锁等),尤其是当我使用 AsyncLock 时?
当 MasterAsync 正在执行时,HumbleSlave1Async 和 HumbleSlave2Async 不能执行。 反之亦然 - 当一个或两个从属服务器正在执行时,主异步不能。 困难的部分 - 奴隶不能互相阻挡。
首先,仔细检查你是否真的想要这个。大多数情况下,代码职责的重组将简化所需的同步(并且通常也更有效)。
也就是说,你的方案适合读取器/写入器锁。RWL 是一种锁,可以采用两种不同的方式,作为"写入器"(不允许同时使用任何其他锁)或作为"读取器"(允许其他读取器,但不允许写入器)。Stephen Toub 这里有一个兼容async
的,我有一个作为我的 AsyncEx 库的一部分。
更新:示例代码:
private readonly AsyncReaderWriterLock _lock = new AsyncReaderWriterLock();
private async Task MasterAsync()
{
using (await _lock.WriterLockAsync())
{
await Task.Delay(2000);
}
}
private async Task HumbleSlave1Async()
{
using (await _lock.ReaderLockAsync())
{
await Task.Delay(5000);
}
}
private async Task HumbleSlave2Async()
{
using (await _lock.ReaderLockAsync())
{
await Task.Delay(5000);
}
}
您的方法可能存在的一个问题是,当HumbleSlave2Async
正在执行时,MasterAsync
已被调用、获取asyncLock1
并正在等待asyncLock2
,您将无法执行HumbleSlave1Async
(因为asyncLock1
被MasterAsync
获取)。因此,您的条件#3将不满足。
也许你应该使用类似AsyncManualResetEvent的东西来做到这一点。
这当然不会死锁,因为您始终以相同的顺序获取锁:
-
_asyncLock1
(或者您不会获得它HumbleSlave2Async
) -
_asyncLock2
(或者您不会获得它HumbleSlave1Async
)
总锁顺序保证了死锁的自由。