Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Await Inside Foreach Keyword

Tags:

c#

.net

foreach

I have a List of Task<bool> that i want to iterate it and depending on the awaited result i decide whether to continue or break but ironically the foreach just executes the tasks and await keyword does not work

Here is my code

private async void Execute(object sender, EventArgs e)
{
    var tList = new List<Task<bool>> { Method1(), Method2()};

    foreach (var task in tList)
    {
        var result = await task;

        if(!result)
            break;
    }
}

public async Task<bool> Method1()
{
    await Task.Delay(1000);
    Console.WriteLine("Method1");
    return false;
}

public async Task<bool> Method2()
{
    await Task.Delay(1000);
    Console.WriteLine("Method2");
    return true;
}

Result : Both functions are execute.

Question : How could i use await inside foreach ?.

And thanks in advance.

like image 669
Roman Ratskey Avatar asked May 02 '13 23:05

Roman Ratskey


People also ask

Can you use await inside a forEach?

forEach is not designed for asynchronous code. (It was not suitable for promises, and it is not suitable for async-await.) For example, the following forEach loop might not do what it appears to do: const players = await this.

Why async does not work in forEach?

The forEach loop was not built to work with asynchronous callback functions which is the reason it does not do what you may be expecting. It does not wait for the promise of an iteration to be resolved before it goes on to the next iteration.

Can we use async-await in forEach C#?

ForEach doesn't play particularly well with async (neither does LINQ-to-objects, for the same reasons). In this case, I recommend projecting each element into an asynchronous operation, and you can then (asynchronously) wait for them all to complete.

Is forEach async or sync?

Note: forEach expects a synchronous function. forEach does not wait for promises. Make sure you are aware of the implications while using promises (or async functions) as forEach callback.


1 Answers

You can use await within a foreach exactly as you are doing now.

Result : Both functions are execute.

Both functions should execute. The result isn't set to false until Method2 returns, at which point both have already run. You're also starting both Task<bool> instances before you await either, so both are (potentially) running before your foreach loop.

Reverse the order of your methods, and they won't both necessarily run (though they may, as you're starting them):

var tList = new List<Task<bool>> { Method2(), Method1()};

If you want to delay this completely, you could write it as:

var tList = new List<Func<Task<bool>>> { Method2, Method1};

foreach (var taskFunc in tList)
{
    var result = await taskFunc();

    if(!result)
        break;
}
like image 97
Reed Copsey Avatar answered Sep 19 '22 02:09

Reed Copsey