Async / await WhenAll by two methods with the same return type

I am trying to upload files asynchronously to an S3 bucket. I can do this successfully with the following code.

I cannot figure out how to handle two different methods that have the same return type at the same time.

UploadImages

and UploadAttachments

both return IEnumerable

of EntityUploadResult

. How do I execute them in Parallel and return the results after they are completed?

public async Task<List<EntityUploadResult>> BulkUploadFiles(IEnumerable<BulkUploadFile> files)
{
    var results = new List<EntityUploadResult>();

    var images = UploadImages(files.Where(x => x.FileType == BulkFileType.Image).AsEnumerable());
    var attachments = UploadAttachments(files.Where(x => x.FileType == BulkFileType.Attachment).AsEnumerable());

    results.AddRange(await images);
    results.AddRange(await attachments);

    return results;
}

private async Task<IEnumerable<EntityUploadResult>> UploadImages(IEnumerable<BulkUploadFile> files)
{
    return await Task.WhenAll(files.Select(i => UploadImage(i)));
}

private async Task<IEnumerable<EntityUploadResult>> UploadAttachments(IEnumerable<BulkUploadFile> files)
{
    return await Task.WhenAll(files.Select(i => UploadAttachment(i)));
}

      

+3


source to share


2 answers


First of all, this is what you are already doing by running both operations and only then waiting for them.

But if you want to do it with Task.WhenAll

and only wait once, you can use the return value, which is the collection of all the return values ​​of the operations, and combine them withSelectMany



public async Task<List<EntityUploadResult>> BulkUploadFiles(IEnumerable<BulkUploadFile> files)
{
    var images = UploadImages(files.Where(x => x.FileType == BulkFileType.Image).AsEnumerable());
    var attachments = UploadAttachments(files.Where(x => x.FileType == BulkFileType.Attachment).AsEnumerable());

    var results = await Task.WhenAll(images, attachments);
    return results.SelectMany(_ => _).ToList();
}

      

+6


source


await

to a WhenAll

with both of them, then review Result

later or if (as in this case) through the returned result WhenAll

:

If the two types are different, you can do so (also an option if the types are the same);

await Task.WhenAll(images, attachments);
var imgResult = images.Result;
var attResult = attachments.Result;

      

If they are of the same type, you can also do:

IEnumerable<IEnumerable<EntityUploadResult>> = await Task.WhenAll(images, attachments);

      



As such your lines:

results.AddRange(await images);
results.AddRange(await attachments);

      

May be replaced by:

results.AddRange((await Task.WhenAll(images, attachments)).SelectMany(u => u));

      

+2


source







All Articles