I am trying to implement a method called ReadAllLinesAsync
using the async feature. I have produced the following code:
private static async Tas
The problem is that you are calling await reader.ReadLineAsync()
in a tight loop that does nothing - except return execution to the UI thread after each await before starting all over again. Your UI thread is free to process windows events ONLY while ReadLineAsync()
tries to read a line.
To fix this, you can change the call to await reader.ReadLineAsync().ConfigureAwait(false)
.
await
waits for the completion of an asynchronous call and returns execution to the Syncrhonization context that called await
in the first place. In a desktop application, this is the UI thread. This is a good thing because it allows you to update the UI directly but can cause blocking if you process the results of the asynchronous call right after the await
.
You can change this behavior by specifying ConfigureAwait(false)
in which case execution continues in a different thread, not the original Synchronization context.
Your original code would block even if it wasn't just a tight loop, as any code in the loop that processed the data would still execute in the UI thread. To process the data asynchronously without adding ConfigureAwait
, you should process the data in a taks created using eg. Task.Factory.StartNew and await that task.
The following code will not block because processing is done in a different thread, allowing the UI thread to process events:
while ((line= await reader.ReadLineAsync()) != null)
{
await Task.Factory.StartNew(ln =>
{
var lower = (ln as string).ToLowerInvariant();
Console.WriteLine(lower);
},line);
}