简体   繁体   中英

UWP - How to start multiple tasks running in parallel?

I have an app where I select multiple (300-500) images then create a video where each image is a frame. In order to load these images into a composition for playback, I need to convert them and save them to temporary memory before they can be loaded. This conversion/save process is taking some time and I'm trying to find ways to speed up the task.

What would be a good way to have multiple instances of this conversion task take place in parallel? Currently, CPU usage is low (4%-6%) while the conversion is taking place.

Here is how I'd like it to work:

  1. User picks multiple image files

  2. A folder in temporary storage is created

  3. Multiple image convert/save tasks are created and run in parallel.

  4. After conversion and save is complete, all converted images in temporary storage folder are selected and loaded into a composition for playback.

Here's what I have now:

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);
}

Basically I'd like to have as many instances of the the CreateImage task running in parallel as possible. Any thoughts as to how I go about doing this?

I tried the following for a selection of 10 images but the images did not seem to be processed in parallel:

    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);

Thanks for any help you can provide!

To let multiple tasks run in parallel, each task have to be composed as a background task. So you need to use Task.Run() or something. Plain async function with Task return type does not yield background 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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM