Reading Large Data files in WPF with IAsyncEnumerable

 


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






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;
}
}
}
view raw MainWindow.cs hosted with ❤ by GitHub
<TextBox x:Name="txtBox"
IsReadOnly="True"
VerticalScrollBarVisibility="Auto"
TextWrapping="Wrap"/>
view raw MainWindow.xaml hosted with ❤ by GitHub

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.