c# - 停止两个异步方法与另一个方法同时运行

标签 c# .net multithreading concurrency async-await

我有两个异步函数,我将它们称为 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 调用不能并发、编写器锁定的限制,但仍然存在调用顺序和完成所有 的要求>DoStuffChangeState 之前完成,反之亦然。(来自@Scott Chamberlain 的提示要同时使用读取器和写入器锁)

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

相关文章:

c# - 将 Sql all 运算符转换为 linq

c# - 为 Selenium WebDriver 查找元素

c# - 如何通过代理服务器使用 API 上传到 YouTube

.net - 是否有SqlExceptions抛出但仍然提交其数据?

c - pthread 空指针转换

c# - 如何使 FakeItEasy 伪造对象的方法在第一次调用时抛出并在第二次调用时返回?

c# - 在 XAML 中重用路径对象

c# - 清除 .NET 的 StringBuilder 内容的最佳方法

导致线程锁定的 C++ 优化

c - 线程 : value stored in heap 问题