-
Notifications
You must be signed in to change notification settings - Fork 6
Open
Description
I don't really know if my usage of the CancellationToken is misguided, but I've been facing several instances of a possible false positive on PH_P007 when using Parallel.ForEachAsync combined with ParallelOptions, as per examples below:
//This triggers PH_P007
public Task Ph7Example(int maxDegreeOfParallelism = 20, CancellationToken ct = default)
{
List<string> source = new();
return Parallel.ForEachAsync(source, new ParallelOptions()
{
MaxDegreeOfParallelism = maxDegreeOfParallelism,
CancellationToken = ct,
},
async (source, ct1) =>
{
await SomeOtherAction(source, ct1);
});
}
//This doesn't
public Task Ph7Example2(int maxDegreeOfParallelism = 20, CancellationToken ct = default)
{
List<string> source = new();
return Parallel.ForEachAsync(source, new ParallelOptions()
{
MaxDegreeOfParallelism = maxDegreeOfParallelism,
}.CancellationToken = ct,
async (source, ct1) =>
{
await SomeOtherAction(source, ct1);
});
}
//Added to example as a random method to pass the CancellationToken
public Task<string> SomeOtherAction(string source, CancellationToken ct = default)
{
return Task.FromResult(source);
}
It's quite confusing for the user to spot the difference (if any) between the two forms. Seems to me that both should trigger or neither.
There is a third form to this, but I find very understandable that it triggers PH, since there's hardly any way to check if the Token was passed on to the inner scope:
//This also triggers, although quite understandably
public Task Ph7Example3(int maxDegreeOfParallelism = 20, CancellationToken ct = default)
{
List<string> source = new();
var options = new ParallelOptions()
{
MaxDegreeOfParallelism = maxDegreeOfParallelism,
CancellationToken = ct,
};
return Parallel.ForEachAsync(source, options,
async (source, ct) =>
{
await SomeOtherAction(source, ct);
});
}
Metadata
Metadata
Assignees
Labels
No labels