Producing and consuming Async sequences
Reading Large Data files in WPF
As soon as you type new Thread()
, it’s over; your project already has legacy code.
An asynchronous foreach will ask the collection object for an enumerator, and will repeatedly ask it to advance to the next item, executing the loop body with the value returned by Current each time, until the enumerator indicates that there are no more items.
The main difference is that the synchronous MoveNext has been replaced by MoveNextAsync, which returns an awaitable ValueTask<T>. (The IAsyncEnumerable<T> interface also provides support for passing in a cancellation token, although an asynchronous foreach won’t use that itself.)
To consume an enumerable source that implements this pattern, you must put the await keyword in front of the foreach. You can also return an IAsyncEnumerable<T>. Code below shows both implementation and consumption of IAsyncEnumerable<T> in action.
TEST 1: Reading stream line by line using IAsyncEnumerable
Reading large 326MB text file 3MLN line by line and displaying in WPF TextBox
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public partial class MainWindow : Window | |
{ | |
public MainWindow() | |
{ | |
InitializeComponent(); | |
Loaded += MainWindow_Loaded; | |
} | |
private async void MainWindow_Loaded(object sender, RoutedEventArgs e) | |
{ | |
await foreach (var line in ReadLinesAsync()) | |
{ | |
//adding delay allows windows to redraw UI Gradually it doesnt work otherwise | |
await Task.Delay(1); | |
Dispatcher.Invoke(() => | |
{ | |
txtBox.AppendText(line); | |
txtBox.ScrollToEnd(); | |
}); | |
} | |
} | |
public async IAsyncEnumerable<string> ReadLinesAsync() | |
{ | |
// File Size 326MB | |
// #record > 3MLN | |
var path = @"./deputies_dataset.csv"; | |
using var bodyTextReader = new StreamReader(path); | |
while (!bodyTextReader.EndOfStream) | |
{ | |
var line = await bodyTextReader.ReadLineAsync(); | |
yield return line; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<TextBox x:Name="txtBox" | |
IsReadOnly="True" | |
VerticalScrollBarVisibility="Auto" | |
TextWrapping="Wrap"/> | |
Reference to the
System.Linq.Async
package, and add a using System.Linq;
declaration, all the LINQ operators will be available on IAsyncEnumerable<T>
expressions.