本文介绍了PLINQ对ConcurrentQueue是不是多线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C#程序如下PLINQ语句:

I have the following PLINQ statement in a C# program:

 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

没有什么是并行运行的:

Nothing is running in parallel:


  • 在运行,总的CPU用法是约30%,这是与其他一切运行了。我有8个内核(超线程与4个物理内核的酷睿i7 720QM),以及8个核心的4几乎没有利用的。其余运行约40%-50%。

  • 磁盘使用率通常为0%,并有除查询到一个Postgres数据库在本地主机上(见下文)没有网络的使用情况。

  • 如果我的地方添加断点内 geocodeThis.Geocode(),Visual Studio中的主题下拉只是说 [ PID 的]主线程。它永远不会去任何其他线程。

  • 我使用 Npgsql 连接到Postgres的,每个线程运行几个选择针对表的查询。我正在运行的pgAdmin III的服务器状态应用程序,它显示的和pg_stat_activity 。通过监测这一点,战略配售断点(见上文),我可以看到应用程序的从不的有正在运行的所有所谓的并发线程开1个多数据库连接 geocodeThis.Geocode( )。即使我添加的池=假到数据库连接字符串,来强制连接不被汇集,我从来没有看到在使用超过1个连接geocodeThis.Geocode()

  • Postgres的表在 WHERE 子句中索引的每一列。即使它被收录不好,我期望大量的磁盘使用情况。如果Postgres的拿着东西以任何其他方式,似乎将浸泡的核心。

  • While running, total CPU usage is about 30%, and this is with everything else running, too. I have 8 cores (Hyper-Threading on a Core i7 720QM with 4 physical cores), and 4 of the 8 cores have virtually no utilization at all. The rest run roughly 40%-50%.
  • Disk usage is usually 0%, and there's no network usage except for queries to a Postgres DB on localhost (see below).
  • If I add a breakpoint somewhere inside geocodeThis.Geocode(), Visual Studio's Thread dropdown just says [pid] Main Thread. It never goes to any other thread.
  • I am using Npgsql to connect to Postgres, and each thread runs a few SELECT queries against a table. I am running pgAdmin III's Server Status app, which shows pg_stat_activity. Through monitoring this, and strategic breakpoint placement (see above), I can see that the app never has more than 1 database connection open for all supposedly concurrent threads running geocodeThis.Geocode(). Even if I add Pooling=false to the DB connection string, to force connections not to be pooled, I never see more than 1 connection used in geocodeThis.Geocode().
  • The Postgres table is indexed on every column in the WHERE clause. Even if it was poorly indexed, I'd expect lots of disk usage. If Postgres was holding things up in any other way, seems like it would soak a core.

这似乎是一个简单PLINQ案例研究,而我抓我的头,为什么什么也没有并行运行。

This seems like a simple PLINQ case study, and I am scratching my head as to why nothing's running in parallel.

推荐答案

您是并行的只是枚举 assertQueue 本身,然后unparallelizing它回到一个普通的的IEnumerable 。这一切都发生在的foreach 循环,甚至开始之前。然后,可以使用普通的的IEnumerable 的foreach 它运行循环连续的身体。

You are parallelizing just the enumeration of the assertQueue itself and then "unparallelizing" it back into an ordinary IEnumerable. This all happens before the foreach loop even starts. Then you use the ordinary IEnumerable with the foreach which runs the body of the loop serially.

有很多方法可以并行运行的循环,但我想到的是使用 Parallel.ForEach 第一位的主体:

There are many ways to run the body of the loop in parallel but the first one that comes to mind is using Parallel.ForEach:

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

这篇关于PLINQ对ConcurrentQueue是不是多线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 15:04