Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async lock not allowed

Basically, I want to make multiple asynchronous requests to a tcp Server. I currently have a working client that is only synchronous and blocks the UI on every network call. Since multiple requests might occur at almost the same time, I tried to do this:

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

I am sure this is not a good use of lock but it's the only way I can think of that could make the calls wait for their turn. Is there an object I can use to achieve this kind of behavior? I thought Monitor would be the same so I didn't try (I understand they're multithreading stuff but that's all I'm familiar with...)

like image 977
Philippe Paré Avatar asked Aug 19 '15 01:08

Philippe Paré


People also ask

Can we use lock in async await?

Using a plain lock won't work because you can't await inside of a lock. I decided to try a SemaphoreSlim as that has a async method.

Can we use lock in async await C#?

The await keyword in C# (. NET Async CTP) is not allowed from within a lock statement. From MSDN: An await expression cannot be used in a synchronous function, in a query expression, in the catch or finally block of an exception handling statement, in the block of a lock statement, or in an unsafe context.

How can we avoid deadlock in async await?

Another solution is to call “ConfigureAwait(false)” on the task of the underlying method, to prevent the continuation of the task on the original context captured. If you really cannot use async all the way, then you could use “Task. Run(…)” to execute the async method in a separate thread.

What is lock C#?

C# Lock keyword ensures that one thread is executing a piece of code at one time. The lock keyword ensures that one thread does not enter a critical section of code while another thread is in that critical section. Lock is a keyword shortcut for acquiring a lock for the piece of code for only one thread.


1 Answers

Looks like the problem that you have is that threads will block while acquiring the lock, so your method is not completely async. To solve this you can use 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();     } } 
like image 181
Jared Moore Avatar answered Sep 17 '22 12:09

Jared Moore