<返回更多

如何在 await,async 中使用 lock锁 ?

2023-09-10  微信公众号  一线码农聊技术
加入收藏

如何在 await,async 中使用 lock锁 ?
咨询区

长话短说,我需要向 tcp server 发起几个异步的 request 请求,同时我的client只能用同步阻塞UI线程的方式进行网络请求,因为是异步发起,多个请求可能会出现并行请求 tcp server 的情况,所以我尝试用 lock 限定 。

private readonly object readLock = new object(); 

public async Task UpdateDetAIlsAsync()
{
    //I want every request to wait their turn before requesting (using the connection) 
    //to prevent a read call from catching any data from another request
    lock (readLock)
    {
        Details details = await connection.GetDetailsAsync();
        detailsListBox.Items = details;
    }
}

但是上面的代码会抛出下面的异常:

 error CS1996: Cannot await in the body of a lock statement

编译器不允许在这里使用 lock ,但我只能这样来强迫 request 请求串行,请问我该如何实现?

回答区

要想在异步中实现串行同步,可以使用 C# 新提供的 SemaphoreSlim.WaitAsync 方法,参考如下代码:

private readonly SemaphoreSlim readLock = new SemaphoreSlim(1, 1); 

public async Task UpdateDetailsAsync()
{
    //I want every request to wait their turn before requesting (using the connection) 
    //to prevent a read call from catching any data from another request
    await readLock.WaitAsync();
    try
    {
        Details details = await connection.GetDetailsAsync();
        detailsListBox.Items = details;
    }
    finally
    {
        readLock.Release();
    }
}

你所遇到的问题,其实 Nito.AsyncEx 早已经帮你解决了,它是一个 Nuget 上非常有名的异步扩展库,很多的开发者也都是从用 AsyncLock 开始的,使用方式和同步模式的 lock 很相似,参考如下代码:

private readonly AsyncLock _mutex = new AsyncLock();

public async Task UseLockAsync()
{
  // AsyncLock can be locked asynchronously
  using (await _mutex.LockAsync())
  {
    // It's safe to await while the lock is held
    await Task.Delay(TimeSpan.FromSeconds(1));
  }
}

更多的内容,可以参考 Github:  https://github.com/StephenCleary/AsyncEx

点评区

AsyncEx 确实是一个非常

关键词:lock锁      点击(2)
声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多lock锁相关>>>