我需要做的是:
(链接到使用过的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时?
答案 0 :(得分:6)
执行MasterAsync时,HumbleSlave1Async和HumbleSlave2Async不能。 副Versa-当一个或两个Slaves正在执行时,MasterAsync不能。 困难部分 - 奴隶不能互相阻挡。
首先,仔细检查你是否真的想要这个。大多数情况下,代码职责的重组将简化您需要的同步(并且通常也更有效)。
那就是说,你的场景适合读者/作者锁定。 RWL是一种锁,可以采用两种不同的方式,作为“作者”(不允许同时进行任何其他锁定)或作为“读者”(允许其他读者而非作者)。 Stephen Toub有一个async
兼容的here,我有AsyncEx library的一部分。
更新:示例代码:
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);
}
}
答案 1 :(得分:1)
您的方法可能存在的问题是,当HumbleSlave2Async
正在执行且MasterAsync
已被调用,已获取asyncLock1
且正在等待asyncLock2
时,您将不会能够执行HumbleSlave1Async
(因为asyncLock1
占用了MasterAsync
)。所以,你的条件#3将不会得到满足。
也许你应该使用类似AsyncManualResetEvent之类的东西来完成这项工作。
答案 2 :(得分:1)
这肯定不会死锁,因为你总是以相同的顺序获取锁:
_asyncLock1
(或者您没有获取HumbleSlave2Async
)_asyncLock2
(或者您没有获取HumbleSlave1Async
)完全锁定命令可确保死锁的自由。