C# Can';在Windows 8 metro应用程序中,无法从StorageFile正确读取所有文件
我正在Windows 8 metro应用程序中开发一个简单的应用程序,并尝试从PicturesLibrary检索文件,我输入的代码如下:C# Can';在Windows 8 metro应用程序中,无法从StorageFile正确读取所有文件,c#,wpf,windows-runtime,async-await,C#,Wpf,Windows Runtime,Async Await,我正在Windows 8 metro应用程序中开发一个简单的应用程序,并尝试从PicturesLibrary检索文件,我输入的代码如下: public async void Initialize() { IReadOnlyList<StorageFile> storageFiles = await KnownFolders.PicturesLibrary.GetFilesAsync(); foreach (var storageFile i
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);
}
}
public异步void Initialize()
{
IReadOnlyList storageFiles=等待KnownFolders.PicturesLibrary.GetFileAsync();
foreach(storageFiles中的var-storageFile)
{
BitmapImage BitmapImage=新的BitmapImage();
FileRandomAccessStream=(FileRandomAccessStream)等待storageFile.OpenAsync(FileAccessMode.Read);
bitmapImage.SetSource(流);
图像=新图像();
image.Source=位图图像;
图片。添加(图片);
}
}
然后我使用它们的图像源显示这些图像。
我遇到的问题是,有时它会显示所有人,有时是一个人
或者,有时它不会显示任何图像,我不明白这是否是因为等待的方法GetFileAsync()或其他我可能缺少的东西
提前感谢:)我想这只是一个时间问题,但是在foreach中做一个断点或跟踪点可以肯定
尝试将此更改为返回任务,然后在调用程序中等待它。您可以我认为您的问题将是这一行
FileRandomAccessStream stream = (FileRandomAccessStream)await storageFile.OpenAsync(FileAccessMode.Read);
在循环中等待可能会给您带来一些奇怪的范围问题。我要做的第一件事是切换这个循环的前两行
FileRandomAccessStream stream = (FileRandomAccessStream)await storageFile.OpenAsync(FileAccessMode.Read);
BitmapImage bitmapImage = new BitmapImage();
可能是正在向您重新输入bitmapImage
引用。如果这没有帮助,您可能需要查看.ContinueWith
方法
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);
});
好的,多亏了你们,我找到了解决方案,我不得不重新安排代码
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;
}
再次感谢各位 为什么不试试非异步方法,看看是否一致地获取所有文件?@jberger-没有这样的API可用,Metro只有像Silverlight以前一样有很多异步。我还不熟悉async/await,但它似乎是
StorageFolder.getFileAsync()
返回一个IAsyncOperation
,它又有一个Completed
事件。到底发生了什么?图像是否在存储文件中,但未显示?或者它们是否在存储文件中丢失了?另外,如果没有必要,您不应该编写async void
方法。内存使用情况如何?看起来您正在将所有图像读取到内存中。谢谢@James,是的,我认为这是一个时间问题,正如您所说,我在foreach循环中尝试了一些断点,效果更好,但由于我对异步操作不太熟悉,我不确定如何实现您的解决方案,如果你给我一些链接,我将非常感谢,再次感谢。只要在方法声明中将void改为Task,然后让调用方等待或.Wait(),这取决于调用方是否可以/应该是异步的。非常感谢@James,我解决了它,现在它工作得很好,谢谢:)我猜使用图像的视图正在获取图像的内容,而此函数仍在将位图放入图像中。这样就可以了,如果图像是可观察的集合,视图可以随着图像的添加而更新。嗨@Chris,我尝试切换这两行,但没有效果,即使没有.ContinueWith()方法的定义。感谢您的帮助。FWIW,您可以将'Wait _imageList.Initialize()'更改为'_imageList.Initialize().Wait()',然后将代码放入ctor(因为它将在该点同步运行,而不是重写)。如果您使用的是异步API,并且不希望调用方是异步的,那么只需正常地与返回的任务交互(例如,调用Wait())就可以了。您只需要在希望调用方也是异步的情况下“等待”:
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);
}
}