I am using the following code to read all the images on a network drive and poplate an ImageControl
with each, and then display them on the screen.
The problem I'm having is that regardless of making PopulateImages()
an async
method, and and running Task.WaitAll
the user interface is still locked up until all the images render.
Am I doing the async/await
incorrectly? What do I need to do to resolve this?
public MainWindow()
{
InitializeComponent();
Loaded += (s, e) => PopulateImages();
}
private async void PopulateImages()
{
string StartDirectory = @"//path/to/network/folder";
Task.WaitAll(Directory
.EnumerateFiles(StartDirectory)
.Select(filename => Task.Run(async () =>
{
Bitmap resizedImage;
using (var sourceStream = File.Open(filename, FileMode.Open))
{
using (var destinationStream = new MemoryStream())
{
await sourceStream.CopyToAsync(destinationStream);
resizedImage = ResizeImage(new Bitmap(destinationStream), 96, 96);
}
}
Dispatcher.BeginInvoke(new Action(() =>
{
var imgControl = new ImageControl(filename, resizedImage);
stackpanelContainer.Children.Add(imgControl);
}));
})).ToArray());
}
You're using Task.WaitAll
- that blocks until all the tasks have completed.
Instead, you should use Task.WhenAll
, which returns a Task
which will itself complete when all the other tasks have completed. You can then await that.
await Task.WhenAll(...);
Although to be honest, unless you need to do anything when the tasks have all completed, you don't need to wait for them at all.
See more on this question at Stackoverflow