Can't read all files properly from StorageFile in Windows 8 metro application
-
07-12-2019 - |
Question
I'm developing a simple application in Windows 8 metro applications and I m trying to retrieve files from PicturesLibrary, the code I put is the following :
public async void Initialize()
{
IReadOnlyList<StorageFile> storageFiles = await KnownFolders.PicturesLibrary.GetFilesAsync();
foreach (var storageFile in storageFiles)
{
BitmapImage bitmapImage = new BitmapImage();
FileRandomAccessStream stream = (FileRandomAccessStream)await storageFile.OpenAsync(FileAccessMode.Read);
bitmapImage.SetSource(stream);
Image image = new Image();
image.Source = bitmapImage;
Images.Add(image);
}
}
then I show these images using their ImageSource. The problem that I am meeting is that sometimes it shows them all, somethimes one or two , sometimes it deosn't show any image, I don't understand if this is because of the awaitable method GetFileAsync() or other things I may be missing.
Thanks in advance :)
Solution
I would guess it's just a timing issue, but doing a breakpoint or trace point in the foreach would tell for sure.
Try changing this to return Task and then await it in the caller of you can
OTHER TIPS
I think your problem will be this line.
FileRandomAccessStream stream = (FileRandomAccessStream)await storageFile.OpenAsync(FileAccessMode.Read);
Awaiting inside a loop is likely going to give you some odd scope issues.
The first thing I would try is switching the first two lines of this loop around.
FileRandomAccessStream stream = (FileRandomAccessStream)await storageFile.OpenAsync(FileAccessMode.Read);
BitmapImage bitmapImage = new BitmapImage();
It could be that the bitmapImage
reference is being repointed on you. If this doesn't help though, you might need to look at the .ContinueWith
method.
storageFile.OpenAsync(FileAccessMode.Read).ContinueWith(task => {
FileRandomAccessStream stream = (FileRandomAccessStream)task.Result;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(stream);
Image image = new Image();
image.Source = bitmapImage;
Images.Add(image);
});
Ok, I found the solution for this thanks to you guys , I had to rearrange the code little bit,
public async Task Initialize()
{
IReadOnlyList<StorageFile> storageFiles = await KnownFolders.PicturesLibrary.GetFilesAsync();
foreach (var storageFile in storageFiles)
{
var image = new Image();
image.Source = await GetBitmapImageAsync(storageFile);
Images.Add(image);
}
}
public async Task<BitmapImage> GetBitmapImageAsync(StorageFile storageFile)
{
BitmapImage bitmapImage = new BitmapImage();
IAsyncOperation<IRandomAccessStream> operation = storageFile.OpenAsync(FileAccessMode.Read);
IRandomAccessStream stream = await operation;
bitmapImage.SetSource(stream);
return bitmapImage;
}
then call all that in the OnNavigateTo event since the constructor can't be async
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
_imageList = new ImagesList();
await _imageList.Initialize();
foreach (var image in _imageList.Images)
{
Image img = new Image() { Source = image.Source };
img.Width = img.Height = 200;
img.Margin = new Thickness(20, 0, 20, 0);
img.ImageFailed += image_ImageFailed;
img.PointerEntered += img_PointerEntered;
img.PointerExited += img_PointerExited;
sp_MainStackPanel.Children.Add(img);
}
}
thanks again guys !