user3284707
user3284707

Reputation: 3351

Simplify Task foreach loop c#

I have a number of foreach loops where I am adding items to a list of Tasks to await on before continuing.

I have the following layout for each, however I feel this is fairly verbose so wanted to see if there was a more succinct way to write this?

I need to catch any errors for each DoTaskOnItem and log this and continue with any other tasks still remaining.

    private async Task DoListOfTasks(List<string> items)
    {
        List<Task> tasks = new List<Task>();
        foreach (var item in items)
        {
            var task = Task.Run(async () =>
            {
                try
                {
                    await DoTaskOnItem(item);
                }
                catch
                {
                    AddErrorMessage($"Error: {item}");
                }
            });

            tasks.Add(task);
        }

        await Task.WhenAll(tasks);
    }

Upvotes: 1

Views: 1604

Answers (1)

Andrei
Andrei

Reputation: 44640

Here is what you can do:

private Task DoListOfTasks(List<string> items)
{
    return Task.WhenAll(items.Select(item => Task.Run<Task>(async () =>
    {
        try
        {
            await DoTaskOnItem(item);
        }
        catch
        {
            AddErrorMessage($"Error: {item}");
        }
    })));
}

I'd move exception handling inside DoTaskOnItem, it would simplify to:

private Task DoListOfTasks(List<string> items)
{
    return Task.WhenAll(items.Select(DoTaskOnItem));
}

And at this point the method DoListOfTasks would not even be necessary as it's too simple.

Upvotes: 4

Related Questions