UWP-如何启动多个并行运行的任务?

时间:2020-07-27 19:24:53

标签: c# multithreading performance xaml uwp

我有一个应用程序,其中我选择了多个(300-500)图像,然后创建一个视频,其中每个图像都是一帧。为了将这些图像加载到合成图像中进行播放,我需要对其进行转换,然后将其保存到临时存储器中,然后才能加载它们。此转换/保存过程需要一些时间,我正在尝试寻找加快任务速度的方法。

什么是并行执行此转换任务的多个实例的好方法?当前,转换正在进行中,CPU使用率很低(4%-6%)。

这是我希望它的工作方式:

  1. 用户选择了多个图像文件

  2. 在临时存储中创建了一个文件夹

  3. 创建并并行运行多个图像转换/保存任务。

  4. 转换和保存完成后,将选择临时存储文件夹中的所有转换图像并将其加载到合成文件中进行播放。

这就是我现在拥有的:

private async Task OpenImageSequence(IReadOnlyList<StorageFile> files)
{

    destFolder = await ApplicationData.Current.TemporaryFolder.CreateFolderAsync(NameNoExt, CreationCollisionOption.GenerateUniqueName);
    var composition = new MediaComposition();

    foreach (StorageFile file in files)
    {
        CreateImage(file);
    }

    IReadOnlyList<StorageFile> fileList = await destFolder.GetFilesAsync();

    foreach (StorageFile imgFile in fileList)
    {
        var clip = await MediaClip.CreateFromImageFileAsync(imgFile, TimeSpan.FromSeconds(frameIncrement));
        composition.Clips.Add(clip);
    }

    MediaStreamSource newImageSequence = composition.GenerateMediaStreamSource(defaultProfile);
    windowsSource = MediaSource.CreateFromMediaStreamSource(newImageSequence);

}

private async Task CreateImage(StorageFile file)
{
    var stream = await file.OpenStreamForReadAsync();
    
    //....Image Conversion Code....//

    var destFile = await destFolder.CreateFileAsync("exrConvert.png", Windows.Storage.CreationCollisionOption.GenerateUniqueName);

    await canvas.SaveAsync(destFile.Path.ToString(), CanvasBitmapFileFormat.Png);
}

基本上,我想让CreateImage任务的尽可能多的实例并行运行。关于我该如何做的任何想法?

我尝试了以下方法来选择10张图像,但是这些图像似乎并未并行处理:

    Task t1 = CreateImage(files.ElementAt(0));
    Task t2 = CreateImage(files.ElementAt(1));
    Task t3 = CreateImage(files.ElementAt(2));
    Task t4 = CreateImage(files.ElementAt(3));
    Task t5 = CreateImage(files.ElementAt(4));
    Task t6 = CreateImage(files.ElementAt(5));
    Task t7 = CreateImage(files.ElementAt(6));
    Task t8 = CreateImage(files.ElementAt(7));
    Task t9 = CreateImage(files.ElementAt(8));
    Task t10 = CreateImage(files.ElementAt(9));

    await Task.WhenAll(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10);

感谢您提供的任何帮助!

1 个答案:

答案 0 :(得分:1)

要让多个任务并行运行,必须将每个任务组成一个后台任务。因此,您需要使用Task.Run()之类的东西。具有Task返回类型的普通异步函数不会产生后台任务。

//foreach (StorageFile file in files)
//{
//    await CreateImage(file);
//}
var tasks_in_background_thread = files.Select(file => Task.Run(async () =>
{
    await CreateImage(file);
}));
await Task.WhenAll(tasks_in_background_thread);