不允许异步锁
本文关键字:异步 不允许 | 更新日期: 2023-09-27 18:08:32
基本上,我想向tcp服务器发出多个异步请求。我目前有一个工作客户端,它只是同步的,并且在每个网络调用上阻塞UI。由于多个请求可能几乎同时发生,所以我尝试这样做:
private object readonly 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;
}
}
我确信这不是锁的好用法,但这是我能想到的唯一可以使调用等待轮到它们的方法。有什么东西可以让我实现这种行为吗?我认为监视器将是相同的,所以我没有尝试(我知道他们是多线程的东西,但这就是我所熟悉的…)
看起来您遇到的问题是线程在获取锁时会阻塞,因此您的方法不是完全异步的。要解决这个问题,可以使用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();
}
}
这个问题已经被NuGet软件包Nito.AsyncEx
巧妙地解决了,截至2015年8月,该软件包的下载量已超过5万次。
async/await的辅助库。#支持。net 4.5/4.0, iOS, Android, Windows Store 8.0, Windows PhoneSilverlight 8.0/7.5, Windows Phone Applications 8.1, Silverlight5.0/4.0及其所有可移植库。
(剪)
# AsyncLock #
许多开发人员开始使用这个库来实现AsyncLock,这是一种异步兼容的互斥机制。使用AsyncLock很简单:
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上查看c#源代码或安装NuGet包Nito.AsyncEx