c# UWP 并行图像加载

c# UWP parallel image loading

我自己有一个 C# UWP 解决方案,我已经定义了特殊清单 broadFileSystemAccess,所以我可以直接从我的 PC 访问所有文件。

现在我正在将一堆图像文件加载到内存中,以便在 GridView 上显示它们。这个任务需要很多时间,我想通过 运行 并行加速它。

foreach (var item in someList)
{
    BitmapImage bitmapImage = new BitmapImage();

    StorageFile file = await StorageFile.GetFileFromPathAsync(item.ImagePath);
    using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read))
    {
        await bitmapImage.SetSourceAsync(fileStream);
    }

    someOtherList.Add(new someModel { ... });
};

在其他一些线程上,我发现了 Parallel.ForEach 的用法 - 但它不支持异步调用。然后我看到一个名为 Dasyncusing Dasync.Collections 的库。然而,使用这个函数只会抛出一个错误,说明一个接口是为应用程序调用的另一个线程编组的(粗略翻译),所以我认为这个库可能也不适合这个任务。

我如何在 C# UWP 应用程序中将其并行化?

您可以启动所有任务,然后使用Task.WhenAll:

等待它们全部完成
Func<Item, Task<BitmapImage>> f = async (item) =>
{
    BitmapImage bitmapImage = new BitmapImage();

    StorageFile file = await StorageFile.GetFileFromPathAsync(item.ImagePath);
    using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read))
    {
        await bitmapImage.SetSourceAsync(fileStream);
    }
    return bitmapImage;
};

BitmapImage[] bitmapImages = await Task.WhenAll(someList.Select(f).ToArray());

一次加载大量图片,会占用大量系统内存。使用多个任务同时读取不同的图片,也会消耗系统资源。

最佳做法是使用数据切割方式读取文件。例如,一次读取 10 张图像,下一次读取其他 10 张图像。而GridView是虚拟化控件,可以在item滚动出显示空间时释放内存。更多信息,可以参考这个案例reply.