23

I'm trying to run a Parallel.ForEachAsync(), but I am getting these two errors:

Error 1:
Argument 2: can not convert from System.Threading.Tasks.ParallelOptions to System.Threading.CancellationToken
Error 2:
Delegate Func<WC, CancellationToken, ValueTask> does not take 1 argument

And this is my code:

public async Task<List<DisplayDto>> GetData()
{
    var options = new ParallelOptions()
    {
        MaxDegreeOfParallelism = 20;
    };

    await Parallel.ForEachAsync(result, options, async OrderNumber => {
        //Do Stuff here. 
    });
}

What must be altered in order for this to work as I want?

0

1 Answer 1

40

Parallel.ForEachAsync expects Func<TSource, CancellationToken, ValueTask> i.e. accepting 2 parameters (first one being an element of collection and second one - CancellationToken), not one. Usage can look like that:

public async Task<List<DisplayDto>> GetData()
{
    var options = new ParallelOptions()
    {
        MaxDegreeOfParallelism = 20
    };

    await Parallel.ForEachAsync(result, options, async (OrderNumber, ct) => {
        // do not forget to use CancellationToken (ct) where appropriate 
        // Do Stuff here. 
    });
 }

Example.

Also can be useful - The need for two cancellation tokens in .NET 6 Parallel.ForEachAsync?

7
  • and the ct in async (OrderNumber, ct) is the CancellationToken? Commented Dec 6, 2021 at 17:37
  • 2
    @DoctorFord yes.
    – Guru Stron
    Commented Dec 6, 2021 at 17:39
  • 1
    There is an issue with your code - you can't actually use (ct) since you never provided it. You need to pass the cancellation token in like this Parallel.ForEachAsync(result, myCancelToken, async (OrderNumber, ct) => { }); Or, it appears you can also assign your token to the CancellationToken property of the ParallelOptions Commented Feb 22, 2022 at 20:06
  • 1
    @snow_FFFFFF "you can't actually use (ct) since you never provided it." - it depends on what do you mean/understand by "use". What I meant by use is to analyze it's canceled state - in this case you actually can cause Parallel.ForEachAsync will provide one if programmer has not (there are situations when ForEachAsync implementation will cancel it, one that I know of - one of the tasks will result in exception). "You need to pass the cancellation token" as I explained - no, it is not required.
    – Guru Stron
    Commented Feb 23, 2022 at 7:46
  • 3
    Thanks for the sample - my first reaction was that nothing was actually using the token, but I do see that the exception does cause it to indicate cancellation. This certainly confirms that the MS documentation isn't clear to me, but hopefully this string of comments will be helpful to someone else :) Commented Feb 24, 2022 at 15:53

Not the answer you're looking for? Browse other questions tagged or ask your own question.