C# WinRT GridView崩溃

C# WinRT GridView崩溃,c#,xaml,gridview,windows-runtime,C#,Xaml,Gridview,Windows Runtime,当显示超过13个(12个或更少)大图像(3264x2448)并缩小为320x180个图像项时,GridView会因非托管异常而崩溃:0x7583A862(combase.dll)处的未处理异常 Xaml: 加载代码: private static async Task<BitmapImage> LoadImage(StorageFile file) { var bitmapImage = new BitmapImage(); var str

当显示超过13个(12个或更少)大图像(3264x2448)并缩小为320x180个图像项时,GridView会因非托管异常而崩溃:0x7583A862(combase.dll)处的未处理异常

Xaml:


加载代码:

private static async Task<BitmapImage> LoadImage(StorageFile file)
    {
        var bitmapImage = new BitmapImage();
        var stream = (FileRandomAccessStream)await file.OpenAsync(FileAccessMode.Read);

        bitmapImage.SetSource(stream);

        stream.CloneStream();
        return bitmapImage;

    }

    public async void GetPictures()
    {
        var queryOptions = new QueryOptions(CommonFileQuery.OrderByName, new[] { ".png", ".jpg" });
        var picturesQuery = await KnownFolders.PicturesLibrary.CreateFileQueryWithOptions(queryOptions).GetFilesAsync();
        foreach (var pictureFile in picturesQuery)
        {
            var bitmap = await LoadImage(pictureFile);
            var img = new Image { Source = bitmap };
            ImagesGridView.Items.Add(img);
        }
    }
private静态异步任务LoadImage(StorageFile)
{
var bitmapImage=新的bitmapImage();
var stream=(FileRandomAccessStream)wait file.OpenAsync(FileAccessMode.Read);
bitmapImage.SetSource(流);
stream.CloneStream();
返回位图图像;
}
公共异步void GetPictures()
{
var queryOptions=newqueryoptions(CommonFileQuery.OrderByName,new[]{.png“,.jpg”});
var picturesQuery=await KnownFolders.PicturesLibrary.CreateFileQueryWithOptions(queryOptions).getFileAsync();
foreach(picturesQuery中的var pictureFile)
{
var位图=等待加载图像(pictureFile);
var img=新图像{Source=bitmap};
ImagesGridView.Items.Add(img);
}
}
崩溃不是在加载图像时发生的,而是在所有加载成功后发生的,应用程序应该在GridView中显示图像。另外,我使用相同图像的副本来确保所有图像都是相同的


在我看来,在应用程序中加载大图像似乎很常见,所以可能我在这里做了一些真正错误的事情?

当您的图像控件只有320x180时,您正在以全分辨率加载图像,因此您试图将3264x2448x4(每像素字节)x13=~400MB的纹理输入到您的视频卡中,这可能有点牵强

尝试使用
StorageFile.GetThumbnailAsync()
加载图像,例如

private static async Task<BitmapImage> LoadImageAsync(StorageFile pictureFile)
{
    using (var stream = await pictureFile.GetThumbnailAsync(
        ThumbnailMode.SingleItem,
        320,
        ThumbnailOptions.ResizeThumbnail))
    {
        var bitmap = new BitmapImage();
        await bitmap.SetSourceAsync(stream);
        return bitmap;
    }
}
专用静态异步任务LoadImageAsync(StorageFile pictureFile)
{
使用(var stream=await pictureFile.GetThumbnailAsync)(
ThumbnailMode.SingleItem,
320,
缩略图选项。调整大小(缩略图)
{
var bitmap=新的位图();
等待位图。设置源同步(流);
返回位图;
}
}

谢谢,我会将此标记为一个答案,但当你们在这里时,我有一个相关的问题:来自web的图像呢?我只测试本地图像,但最终我需要从网络上获取大图像(可能没有那么大,但数量更多),我无法获得它们的缩略图(我猜),我应该下载大图像,然后手动调整其网格大小,并在内存中保留原始图像吗?因为下载两次似乎浪费了带宽(用于网格和图像放大)。这是一个单独的问题,根据您的场景有很多答案。1.你应该从网上获取大量图片的缩略图。2.您可以获取完整版本,将其保存在本地,然后从中加载缩略图(
GetThumbnailAsync()
将为您生成新的缩略图)。3.您可以对下载的文件使用一些缓存—或者依赖于web堆栈,或者构建自己的缓存。4.您应该确保列表控件在默认情况下使用虚拟化显示内容,但如果更改
ItemsPanel
模板,则可以停止。
private static async Task<BitmapImage> LoadImageAsync(StorageFile pictureFile)
{
    using (var stream = await pictureFile.GetThumbnailAsync(
        ThumbnailMode.SingleItem,
        320,
        ThumbnailOptions.ResizeThumbnail))
    {
        var bitmap = new BitmapImage();
        await bitmap.SetSourceAsync(stream);
        return bitmap;
    }
}