我有两个异步函数,我将它们称为ChangeState()DoThing()。它们每个都等待下游异步方法。这些是从事件处理程序中调用的,因此它们在执行时不会阻塞任何其他代码。如果调用ChangeState(),则必须先完成DoThing()的所有操作,然后ChangeState()才能执行其操作。仍可以在执行时再次调用ChangeState()。在DoThing()可以继续之前,应先完成DoThing()之前开始的所有执行。

反之亦然。 ChangeState()应该等待,直到之前运行的DoStuff()完成为止。

如何在没有死锁危险的情况下实现此目的?

我知道在锁语句中不允许等待,这是有充分的理由的,这就是为什么我不尝试重新创建该功能的原因。

async void ChangeState(bool state)
{
 //Wait here until any pending DoStuff() is complete.
 await OutsideApi.ChangeState(state);
}

async void DoStuff()
{
 //Wait here until any pending ChangeState() is complete.
 await OutsideApi.DoStuff();
}

最佳答案

根据您的要求,似乎ReaderWriterLock可以为您提供帮助。另外,由于您具有async方法,因此应使用async锁定。不幸的是,.NET框架本身不提供等待就绪的ReaderWriterLock锁。幸运的是,您可以看看AsyncEx库或此article。该示例使用AsyncEx

var readerWriterLock = new AsyncReaderWriterLock();

async void ChangeState(bool state)
{
    using(await readerWriterLock.ReaderLockAsync())
    {
        await OutsideApi.ChangeState(state);
    }
}

async void DoStuff()
{
    using(await readerWriterLock.WriterLockAsync())
    {
        await OutsideApi.DoStuff();
    }
}

n.b. 此解决方案仍然存在以下局限性:不能同时进行DoStuff调用,编写者锁定,但是仍然要满足调用的顺序以及在满足DoStuff之前完成所有ChangeState的要求,反之亦然。(@ Scott Chamberlain的技巧是同时使用两者读者和作家锁)

关于c# - 阻止两个异步方法同时运行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55663540/

10-10 03:03