不允许异步锁定

基本上,我想向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; } } 

我确信这不是一个很好用的锁,但这是我能想到的唯一方法,可以让电话等待轮到他们。 有没有我可以用来实现这种行为的对象? 我认为Monitor会是一样的所以我没有尝试(我知道他们是multithreading的东西,但这就是我所熟悉的……)

看起来你遇到的问题是线程在获取锁时会阻塞,因此你的方法不是完全异步的。 要解决此问题,您可以使用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 try { await readLock.WaitAsync(); Details details = await connection.GetDetailsAsync(); detailsListBox.Items = details; } finally { readLock.Release(); } } 

NuGet软件包Nito.AsyncEx已经Nito.AsyncEx解决了这个问题,截至2015年8月,该软件包的下载次数超过50,000次。

来自自述文件:

AsyncEx async / await的辅助库。

支持.NET 4.5 / 4.0,iOS,Android,Windows Store 8.0,Windows Phone Silverlight 8.0 / 7.5,Windows Phone应用程序8.1,Silverlight 5.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