如何将 'lock' 重构为 'async/await'?

How to refactor 'lock' to 'async/await'?

我们有一个用 C# 目标框架 2.0 编写的旧库。最近准备在一个现代的.net core项目中使用它,打算用async/await。然而,旧图书馆有很多 lock 块。

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

例如,

旧代码

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

预期结果

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

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

您可以使用 SemaphoreSlim, but if there's a lot of it, the AsyncLock library 可能会使转换更容易(和更清洁)。

只需使用 AsyncLock 库并放松。

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

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

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

话虽如此,如果您想将等待锁的方法重构为异步等待 lock/semaphore 的异步方法,您应该使用 SemaphoreSlimawait WaitAsync 电话。这样,异步方法将在 SemaphoreSlim 阻塞执行时放弃控制,并在稍后的某个时间恢复执行。