gpt4 book ai didi

c# - ConcurrentQueue 上的 PLINQ 不是多线程

转载 作者:行者123 更新时间:2023-11-29 11:55:52 36 4
gpt4 key购买 nike

我在 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);
}

两者arrestQueuewriteQueueConcurrentQueues .

没有任何东西并行运行:

  • 运行时,CPU 总使用率约为 30%,其他所有程序都在运行时也是如此。我有 8 个核心(具有 4 个物理核心的 Core i7 720QM 上的超线程),8 个核心中的 4 个几乎根本没有利用率。其余的大约占 40%-50%。
  • 磁盘使用率通常为 0%,并且除了对本地主机上的 Postgres 数据库进行查询之外没有任何网络使用率(见下文)。
  • 如果我在 geocodeThis.Geocode() 内的某处添加断点,Visual Studio 的线程下拉列表仅显示[pid]主线程。它永远不会进入任何其他线程。
  • 我正在使用Npgsql连接到 Postgres,每个线程对表运行一些 SELECT 查询。我正在运行 pgAdmin III 的服务器状态应用程序,它显示 pg_stat_activity。通过监视这一点以及战略性断点放置(见上文),我可以看到该应用从来没有为所有运行 geocodeThis.Geocode() 的假定并发线程打开超过 1 个数据库连接。 。即使我将 Pooling=false 添加到数据库连接字符串中,以强制不合并连接,我也从未看到 geocodeThis.Geocode() 中使用了超过 1 个连接。 .
  • Postgres 表在 WHERE 子句中的每一列上建立索引。即使它的索引很差,我也会期望大量的磁盘使用。如果 Postgres 以任何其他方式阻止事情,看起来它会浸泡一个核心。

这似乎是一个简单的 PLINQ 案例研究,我很困惑为什么没有任何东西并行运行。

最佳答案

您仅并行化 assertQueue 本身的枚举,然后将其“非并行化”回普通的 IEnumerable。这一切都发生在 foreach 循环开始之前。然后,您将普通的 IEnumerableforeach 一起使用,它串行运行循环体。

并行运行循环体的方法有很多,但首先想到的是使用 Parallel.ForEach:

Parallel.ForEach(arrestQueue, arrest =>
{
Geocoder geocodeThis = new Geocoder(arrest);
writeQueue.Enqueue(geocodeThis.Geocode());
Console.Out.WriteLine("Enqueued " + ++k);
});

关于c# - ConcurrentQueue 上的 PLINQ 不是多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6086111/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com