AsyncLock用于多种方法配置

时间:2013-10-21 09:22:24

标签: c# locking async-await

我需要做的是:

  1. 执行MasterAsync时,HumbleSlave1Async和HumbleSlave2Async不能。
  2. 副Versa-当一个或两个Slaves正在执行时,MasterAsync不能。
  3. 困难部分 - 奴隶不能互相阻挡。
  4. (链接到使用过的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时?

3 个答案:

答案 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)

这肯定不会死锁,因为你总是以相同的顺序获取锁:

  1. _asyncLock1(或者您没有获取HumbleSlave2Async
  2. _asyncLock2(或者您没有获取HumbleSlave1Async
  3. 完全锁定命令可确保死锁的自由。