【发布时间】:2014-11-05 23:09:35
【问题描述】:
我有一个使用 PLINQ 并行化的计算,如下所示:
-
Source
IEnumerable<T> source正在提供从 文件。 -
我有一个重量级计算
HeavyComputation我需要做 每个T,我希望这些跨线程分流,所以我 使用 PLINQ,例如:AsParallel().Select(HeavyComputation)
这里是有趣的地方:由于文件的限制
提供source 的阅读器类型,我需要source
在初始线程上枚举,而不是在并行工作者上。我需要
source 的完整评估将 绑定 到主
线。然而,似乎来源实际上是在工人身上列举的
线程。
我的问题是:有没有一种直接的方法可以修改此代码以
将source 的枚举绑定到初始线程,而
将繁重的工作分给并行工人?请记住,
只是在AsParallel() 之前做一个急切的.ToList() 不是这里的选择,
因为来自文件的数据流很大。
下面是一些示例代码,可以演示我看到的问题:
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System;
public class PlinqTest
{
private static string FormatItems<T>(IEnumerable<T> source)
{
return String.Format("[{0}]", String.Join(";", source));
}
public static void Main()
{
var expectedThreadIds = new[] { Thread.CurrentThread.ManagedThreadId };
var threadIds = Enumerable.Range(1, 1000)
.Select(x => Thread.CurrentThread.ManagedThreadId) // (1)
.AsParallel()
.WithDegreeOfParallelism(8)
.WithExecutionMode(ParallelExecutionMode.ForceParallelism)
.AsOrdered()
.Select(x => x) // (2)
.ToArray();
// In the computation above, the lambda in (1) is a
// stand in for the file-reading operation that we
// want to be bound to the main thread, while the
// lambda in (2) is a stand-in for the "expensive
// computation" that we want to be farmed out to the
// parallel worker threads. In fact, (1) is being
// executed on all threads, as can be seen from the
// output.
Console.WriteLine("Expected thread IDs: {0}",
FormatItems(expectedThreadIds));
Console.WriteLine("Found thread IDs: {0}",
FormatItems(threadIds.Distinct()));
}
}
我得到的示例输出是:
Expected thread IDs: [1]
Found thread IDs: [7;4;8;6;11;5;10;9]
【问题讨论】:
-
您可以遍历 (1) 中的可枚举并在循环中生成工作任务。在循环结束时等待所有任务。
-
谢谢@Asad,我不确定这是否能让我控制并行度。会吗?或许你能提供更多细节。
标签: c# multithreading linq parallel-processing plinq