我有两个异步函数,我将它们称为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/