Bloqueo Async no permitido

Básicamente, quiero hacer múltiples solicitudes asincrónicas a un servidor tcp. Actualmente tengo un cliente en funcionamiento que solo es síncrono y bloquea la IU en cada llamada de red. Como las solicitudes múltiples pueden ocurrir casi al mismo tiempo, traté de hacer esto:

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; } } 

Estoy seguro de que este no es un buen uso de la cerradura, pero es la única forma en que se me ocurre que podría hacer que las llamadas aguarden su turno. ¿Hay algún objeto que pueda usar para lograr este tipo de comportamiento? Pensé que Monitor sería el mismo, así que no lo intenté (entiendo que sean de múltiples hilos, pero eso es todo lo que estoy familiarizado …)

Parece que el problema que tienes es que los hilos se bloquearán mientras adquieres el locking, por lo que tu método no es completamente asincrónico. Para resolver esto puedes usar 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(); } } 

Este problema ha sido resuelto cuidadosamente por el paquete Nito.AsyncEx que tiene más de 50,000 descargas a partir de agosto de 2015.

Del Léame:

AsyncEx Una biblioteca auxiliar para async / await.

Admite .NET 4.5 / 4.0, iOS, Android, Windows Store 8.0, Windows Phone Silverlight 8.0 / 7.5, Windows Phone Applications 8.1, Silverlight 5.0 / 4.0 y todas las bibliotecas portátiles de los mismos.

[recorte]

AsyncLock

Muchos desarrolladores comienzan a usar esta biblioteca para AsyncLock, un mecanismo de exclusión mutua compatible con asincronía. Usar AsyncLock es sencillo:

 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)); } } 

Vea el código fuente de C # en GitHub o instale el paquete Nito.AsyncEx .