在 IEnumerable 上使用 AsParallel - 它是否具有并行性的任何好处?

Using AsParallel on an IEnumerable - Will it have any benefit of parallelism at all?

IEnumerable<char> GetChars()
        {
            int i = int.MinValue;
            while (i++ < int.MaxValue)
            {
                yield return (char)('A' + (i % 26));
            }
        }

AsParallel应用于上述可枚举字符有什么好处吗?

GetChars().AsParallel().REST_OF_THE_QUERY

因为,据我所知,要在多个线程上并行工作,需要为并行可用的不同线程划分数据分区。但在这里我认为枚举器将是一个瓶颈,因为它不能 运行 并行?

AsParallel 能否从此枚举器并行获取数据并利用多线程的优势?

关于查询:

GetChars().AsParallel().REST_OF_THE_QUERY

REST_OF_THE_QUERY 将被并行化。 GetChars 不会被并行化,并且 运行 在当前线程 中独占。 AsParallel 并行化它后面的内容(只要每个后续运算符 returns 一个 ParallelQuery)。它不会并行化之前的内容。


更新: GSerg 在评论中指出,GetChars().AsParallel() 当前线程 ID 在 GetChars 中不断变化,尽管它出现涉及一些锁定,因为没有两个线程同时进入 GetChars。我的实验符合这些观察结果。这意味着 PLINQ 库不能用于查询需要线程关联的数据源。例如下面的代码在 WinForms 中抛出异常:

private void Button1_Click(object sender, EventArgs e)
{
    Control.CheckForIllegalCrossThreadCalls = true;
    int count = GetHandles().AsParallel().Count();
    MessageBox.Show($"Controls: {count}");
}

private IEnumerable<IntPtr> GetHandles()
{
    foreach (Control control in this.Controls)
    {
        yield return control.Handle;
    }
}

InvalidOperationException: Cross-thread operation not valid: Control 'Button1' accessed from a thread other than the thread it was created on.

没有.AsParallel(),不会抛出异常。