在C# 8 / Unity 2022中,为什么PLINQ Select + FirstOrDefault是以顺序模式执行的?

问题描述 投票:0回答:1

这是有问题的代码:

var raw = Enumerable.Range(1, 10);

var candidates = raw.AsParallel();

var p1 = candidates.AsParallel()
    .SelectMany(
        ii =>
        {
            Debug.Log(">>>>> " + ii);

            Thread.Sleep(1000);

            // for each connection, setup a monitor stream
            // immediately start reading it and ensure that >= 1 heartbeat is received in the first 2 seconds
            // if not, connection is deemed invalid & closed

            try
            {
                return new[] { 3 };
            }
            finally
            {
                Debug.Log("<<<<< " + ii);
            }
        }
    );

var p2 = p1.Select(
    (v, i) =>
    {
        if (i != 0) return 0;
        return v;
    }
);

var chosen = p2.FirstOrDefault();

执行后,它给出以下日志:

>>>>> 1
<<<<< 1
>>>>> 2
<<<<< 2
>>>>> 3
<<<<< 3
>>>>> 4
<<<<< 4
>>>>> 5
<<<<< 5
>>>>> 6
<<<<< 6
>>>>> 7
<<<<< 7
>>>>> 8
<<<<< 8
>>>>> 9
<<<<< 9
>>>>> 10
<<<<< 10

并花了10秒来执行。理论上,执行时应该需要 1 秒并立即达到

>>>>> x

此行为的原因是什么以及如何解决

c# parallel-processing plinq
1个回答
0
投票

SelectMany
的内部机制似乎影响了 PLINQ 处理数据的方式。
ParallelExecutionMode.ForceParallelism
似乎解决了它:

var candidates = raw.AsParallel()
    .WithExecutionMode(ParallelExecutionMode.ForceParallelism);

var p1 = candidates
    .SelectMany(...)
© www.soinside.com 2019 - 2024. All rights reserved.