This is because the ForEachAsync implementation does not expect delegated action.
moveNextTask = enumerator.MoveNextAsync(cancellationToken); action(current);
see https://github.com/mono/entityframework/blob/master/src/EntityFramework/Infrastructure/IDbAsyncEnumerableExtensions.cs#L19
But this is because you cannot wait for the action, the delegate must be Func, which returns the task - see How do you implement the delegation method of asynchronous actions?
Therefore, until Microsoft provides a signature that includes the Func delegate and calls it waiting, you will have to reverse your own extension method. At the moment I am using the following.
public static async Task ForEachAsync<T>( this IQueryable<T> enumerable, Func<T, Task> action, CancellationToken cancellationToken) //Now with Func returning Task { var asyncEnumerable = (IDbAsyncEnumerable<T>)enumerable; using (var enumerator = asyncEnumerable.GetAsyncEnumerator()) { if (await enumerator.MoveNextAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)) { Task<bool> moveNextTask; do { var current = enumerator.Current; moveNextTask = enumerator.MoveNextAsync(cancellationToken); await action(current); //now with await } while (await moveNextTask.ConfigureAwait(continueOnCapturedContext: false)); } } }
In this case, the source test code in your OP will work as expected.
Todd Apr 22 '15 at 3:19 2015-04-22 03:19
source share