Why does this async method lock up the user interface?

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());
}
Jon Skeet
people
quotationmark

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.

people

See more on this question at Stackoverflow