Reputation: 3569
A UWP app, a collection of view models is instantiated and populated in the page's constructor. Each item has a property called ImageSource
of type BitmapImage
, initialized to a new BitmapImage()
. The view has a Grid View bound to the collection. In the view, a DataTemplate
is defined for the items of the collection. The DataTemplate
, in particular, shows an image whose source is bound to the item's property ImageSource
. The DataTemplate
also handles events of Image, so it displays a placeholder while the image is still loading.
The page's Loaded event triggers the download of all image source:
private async void Page_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
foreach (ImageViewModel imageViewModel in this.imageViewModels)
{
IRandomAccessStream randomAccessStream = await SlowImageSourceProvider.GetRandomAccessStream(imageViewModel.Id);
await imageViewModel.ImageSource.SetSourceAsync(randomAccessStream);
}
}
In this code, an instance of IRandomAccessStream
is retrieved from a slow provider, like an HttpClient
listening on a slow network.
The Image.Source on the view are bound to the imageViewModel.ImageSource
of the code above. In such a way, each image needs to wait for the previous one to end its downloading, before starting to download its own source.
How is it possible to make all images to start downloading at once, without them to wait for the others?
The only idea I had was to create a lazy implementation of IRandomAccessStream, but I wander if there is a better way of doing it.
Thanks!
Upvotes: 2
Views: 595
Reputation: 7091
The images will only download one at a time because the foreach
will not start another iteration until both await
statements complete. To request all images download concurrently and wait for them to complete asynchronously try the following:
private async void Page_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) {
var setImageTasks = this.imageViewModels.Select(async imageViewModel => {
var randomAccessStream = await SlowImageSourceProvider.GetRandomAccessStream(imageViewModel.Id);
await imageViewModel.ImageSource.SetSourceAsync(randomAccessStream);
}).ToArray();
await Task.WhenAll(setImageTasks);
}
Upvotes: 1