问题
Parallel.For(0, Height, new ParallelOptions { MaxDegreeOfParallelism = 6 }, y =>
{
int currentLine = y * BMPData.Stride;
for (int x = 0; x < Width; x = x + BPX)
{
var b = pixels[currentLine + x];
var g = pixels[currentLine + x + 1];
var r = pixels[currentLine + x + 2];
int avg = (r + g + b) / 3;
pixels[currentLine + x] = (byte)avg;
pixels[currentLine + x + 1] = (byte)avg;
pixels[currentLine + x + 2] = (byte)avg;
}
});
This is basically a parallel code where it turns bitmap data pixels into gray ones, but is there any way I can replace the Parallel.For
usage with Parallel Linq? I know there's no point to this, but it's required for a certain assignment
回答1:
You can use Enumerable.Range
, and ForAll
to get similar results. Although note ForAll
will not process the list in any stable order - which is probably fine for your use case
Enumerable.Range(0,Height)
.AsParallel()
.WithDegreeOfParallelism(6)
.ForAll(y =>
{
/// existing code here
});
回答2:
The ForAll Operator paragraph in the Introduction to PLINQ article has a ForAll example and ForAll seems to be perfect for what you do.
This example could be modified to your case
var nums = Enumerable.Range(0, Height);
var query =
from num in nums.AsParallel().WithDegreeOfParallelism(6)
select num;
// Process the results as each thread completes
query.ForAll(e => MakeGray(e));
where MakeGray is your pixel setting method.
This doesn't do any better than Jamiec's answer, but has some more fluff which may or may not be what you're looking for.
BTW. I think you could eliminate the 2nd for loop by using
Parallel.For(0, Width * Height / BPX, ...)
or
Enumerable.Range(0, Width * Height / BPX).AsParallel()...
and currentLine + x
would just become x
.
来源:https://stackoverflow.com/questions/65354440/how-to-convert-parallel-for-to-plinq