如何将 '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 的异步方法,您应该使用 SemaphoreSlim
和 await
WaitAsync
电话。这样,异步方法将在 SemaphoreSlim 阻塞执行时放弃控制,并在稍后的某个时间恢复执行。
我们有一个用 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 的异步方法,您应该使用 SemaphoreSlim
和 await
WaitAsync
电话。这样,异步方法将在 SemaphoreSlim 阻塞执行时放弃控制,并在稍后的某个时间恢复执行。