【问题标题】:How to refactor 'lock' to 'async/await'?如何将“锁定”重构为“异步/等待”?
【发布时间】:2023-03-15 21:25:01
【问题描述】:

我们有一个用 C# 目标框架 2.0 编写的旧库。最近我们打算在一个现代.net核心项目中使用它,并打算使用async/await。但是,旧库有很多 lock 块。

我们计划添加新的async 方法来实现相同的逻辑。

例如,

旧代码

void GetOrder()
{
    // ...
    lock(_lock)
    {
    //...
    }
}

预期结果

async Task AsyncGetOrder()
{
    // ...
    await DoSomethingWithLock()
}

请给我一些关于如何将lock 翻译成async/await 的建议。

【问题讨论】:

  • Async/Await 不是锁定的替代方案。
  • SemaphoreSlim()
  • 您是否在寻求一种在异步方法中提供线程安全的方法?
  • 您是要重写旧库,还是打算按原样使用它?
  • @TheodorZoulias @Llama 我正在尝试实现相同的逻辑。我听说asynclock 不应该一起工作。

标签: c# async-await thread-synchronization


【解决方案1】:

您可以使用SemaphoreSlim,但如果有很多,AsyncLock library 可能会使转换更容易(更简洁)。

只需使用 AsyncLock 库并放松一下。

【讨论】:

  • 那个库看起来有点过头了
  • 过度烘烤是什么意思,缺点是什么?还需要考虑性能需求,在做出决定之前需要比较两种解决方案的性能——因为他会经常使用它。
【解决方案2】:

首先需要考虑的是异步方法可以调用非异步方法,但非异步方法调用异步方法并等待它们完成并非易事。

这意味着每个包含lock 的方法可能只需要由异步方法调用。您可以对异步方法进行阻塞等待,但是重构没有意义,您必须非常小心以避免死锁。

您还需要注意,在某些项目类型中,执行线程的身份很重要。例如,在 WPF 中,有些事情只允许 UI 线程执行,如果您启动 Task 从线程池中的线程运行此类代码,您可能会遇到异常。

话虽如此,如果你想将一个等待锁的方法重构为一个异步等待锁/信号量的异步方法,你应该使用SemaphoreSlimawaitWaitAsync调用。这样,当 SemaphoreSlim 阻塞执行时,异步方法将产生控制权,并在稍后恢复执行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-26
    • 2018-04-20
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多