我在C#程序中有以下PLINQ语句:
foreach (ArrestRecord arrest in
from row in arrestQueue.AsParallel()
select row)
{
Geocoder geocodeThis = new Geocoder(arrest);
writeQueue.Enqueue(geocodeThis.Geocode());
Console.Out.WriteLine("Enqueued " + ++k);
}
arrestQueue
和writeQueue
都是ConcurrentQueues。
没有任何东西并行运行:
geocodeThis.Geocode()
内的某处添加断点,则Visual Studio的线程下拉列表会显示 [ pid ]主线程。它永远不会进入任何其他线程。geocodeThis.Geocode()
的所谓并发线程打开了多个数据库连接。即使我将 Pooling = false 添加到数据库连接字符串中,为了强制连接不被合并,我也从未在geocodeThis.Geocode()
中看到多于1个连接。这看起来像是一个简单的PLINQ案例研究,我为什么没有并行运行而感到头疼。
答案 0 :(得分:5)
您只是对assertQueue
本身的枚举进行并行化,然后将其“平行化”回到普通的IEnumerable
。这一切都发生在foreach
循环开始之前。然后你使用普通的IEnumerable
和foreach
串行运行循环体。
有许多方法可以并行运行循环体,但首先想到的是使用Parallel.ForEach
:
Parallel.ForEach(arrestQueue, arrest =>
{
Geocoder geocodeThis = new Geocoder(arrest);
writeQueue.Enqueue(geocodeThis.Geocode());
Console.Out.WriteLine("Enqueued " + ++k);
});
答案 1 :(得分:1)
对并行集合的Foreach仍然是单线程操作。 .AsParallel返回一个集合,该集合定义了一个.ForAll方法,该方法可能(但通过契约并不总是)并行运行。代码将是:
arrestQueue.AsParallel().ForAll(arrest=>
{
Geocoder geocodeThis = new Geocoder(arrest);
writeQueue.Enqueue(geocodeThis.Geocode());
Console.Out.WriteLine("Enqueued " + ++k);
});