我有两个异步函数,我将它们称为 ChangeState()
和 DoThing()
。他们每个人都在等待下游异步方法。这些调用来自事件处理程序,因此它们在执行时不会阻塞任何其他代码。如果 ChangeState()
被调用,则 DoThing()
必须在任何先前的 ChangeState()
完成之前不执行它的操作。 ChangeState()
可以在它仍在执行时再次调用。在 DoThing()
之前开始的任何执行都应该在 DoThing()
可以继续之前完成。
反之亦然; ChangeState()
应该等到任何先前运行的 DoStuff()
完成。
如何在没有死锁危险的情况下实现它?
我知道在 lock 语句中不允许等待,这是有充分理由的,这也是我不尝试重新创建该功能的原因。
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/