Reputation:
I want to execute a for loop in C# in parallel asynchronously. But the Parallel
class contains only a synchronous For
method and an asynchronous ForEachAsync
method (.NET 6). This looks like an oversight to me.
Where is the Parallel.ForAsync
method? Is there any workaround?
Upvotes: 3
Views: 2619
Reputation:
I agree,
not having a Parallel.ForAsync
method looks like an enormous oversight.
I have good news for you though:
in .NET 8 and C#12 (coming out soon at 23. november 2023) this will be resolved.
Upvotes: 9
Reputation: 186813
Well, if you can't wait / use .NET 8, you can try to mimic ForAsync
with a help of ForEachAsync
which is supported from .NET 6 on. To loop over some enumerable (array, list, etc.) while having index
:
// Must be IEnumerable<T>
var data = ...;
await Parallel.ForEachAsync(data.Select((value, index) => (value, index)),
async (pair, token) => {
var value = pair.value;
var index = pair.index;
//TODO: relevant code here
});
If you want to have async version for for (int i = 0; i < n; ++i)
loop then
int n = ...;
await Parallel.ForEachAsync(Enumerable.Range(0, n), async (i, token) => {
//TODO: relevant code here
});
Upvotes: 4
Reputation: 43845
The Parallel.ForAsync
API will be available starting from .NET 8 (release scheduled for November 14, 2023). It has the three following overloads:
public static Task ForAsync<T>(T fromInclusive, T toExclusive,
Func<T, CancellationToken, ValueTask> body)
where T : notnull, IBinaryInteger<T>;
public static Task ForAsync<T>(T fromInclusive, T toExclusive,
CancellationToken cancellationToken, Func<T, CancellationToken, ValueTask> body)
where T : notnull, IBinaryInteger<T>;
public static Task ForAsync<T>(T fromInclusive, T toExclusive,
ParallelOptions parallelOptions, Func<T, CancellationToken, ValueTask> body)
where T : notnull, IBinaryInteger<T>;
It is the first public .NET API to be based on the generic math interfaces introduced in .NET 7.
Usage example:
ParallelOptions options = new() { MaxDegreeOfParallelism = 2 };
await Parallel.ForAsync(0, 100, options, async (i, ct) =>
{
// Process the i element (here the type of i is int)
});
More information and benchmarks about this API can be found in this Microsoft document. Also here is the API proposal.
Upvotes: 3