c# - Parallel Linq - 使用比处理器更多的线程(对于非 CPU 绑定(bind)任务)

标签 c# linq multithreading

我正在使用并行 linq,我正在尝试使用如下基本代码同时下载许多 url:

int threads = 10;
Dictionary<string, string> results = urls.AsParallel( threads ).ToDictionary( url => url, url => GetPage( url );

由于下载网页受网络限制而不是 CPU 限制,因此使用比我的处理器/内核数量更多的线程是非常有益的,因为每个线程的大部分时间都花在等待网络 catch 。然而,根据在我的双核机器上运行 threads = 2 与 threads = 10 具有相同性能的事实判断,我认为发送到 AsParallel 的线程数受限于核心数。

有什么方法可以覆盖这种行为吗?是否有没有此限制的类似库可用?

(我找到了这样一个 python 库,但需要在 .Net 中工作的东西)

最佳答案

这些 URL 是否指向同一台服务器?如果是这样,可能是您达到了 HTTP 连接限制而不是线程限制。有一种简单的方法可以判断 - 将您的代码更改为:

int threads = 10;
Dictionary<string, string> results = urls.AsParallel(threads)
    .ToDictionary(url => url, 
                  url => {
                      Console.WriteLine("On thread {0}",
                                        Thread.CurrentThread.ManagedThreadId);
                      return GetPage(url);
                  });

编辑:嗯。我无法通过一些示例代码使 ToDictionary() 完全 并行化。它适用于 Select(url => GetPage(url)) 但不适用于 ToDictionary。将搜索一下。

编辑:好的,我仍然无法使 ToDictionary 并行化,但您可以解决这个问题。这是一个简短但完整的程序:

using System;
using System.Collections.Generic;
using System.Threading;
using System.Linq;
using System.Linq.Parallel;

public class Test
{

    static void Main()
    {
        var urls = Enumerable.Range(0, 100).Select(i => i.ToString());

        int threads = 10;
        Dictionary<string, string> results = urls.AsParallel(threads)
            .Select(url => new { Url=url, Page=GetPage(url) })
            .ToDictionary(x => x.Url, x => x.Page);
    }

    static string GetPage(string x)
    {
        Console.WriteLine("On thread {0} getting {1}",
                          Thread.CurrentThread.ManagedThreadId, x);
        Thread.Sleep(2000);
        return x;
    }
}

那么,这使用了多少个线程? 5. 为什么?天知道。我有 2 个处理器,所以不是这样 - 我们指定了 10 个线程,所以不是这样。即使我更改 GetPage 以锤击 CPU,它仍然使用 5。

如果您只需要将它用于一项特定任务 - 并且您不介意稍微有点臭的代码 - 老实说,您最好自己实现它。

关于c# - Parallel Linq - 使用比处理器更多的线程(对于非 CPU 绑定(bind)任务),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/612253/

相关文章:

c# - 如何在 Visual Studio 中查看下载包的源代码

c# - 使用 Linq 的具有预定义类型的 GroupBy

c++ - thread_local 单例默认执行延迟初始化?

python - 在 python 中的类中启动无限循环线程后继续执行代码

c# - 检索发票时检索发票详细信息

C# 线程中断停止工作

c# - 链接取消 token

c# - 如果我在 C# 中的 Main 方法是私有(private)的,为什么我的程序可以运行?

c# - 单元测试执行期间 Windows 8 Appx 安装超时

c# - 提高 LINQ 枚举器内条件查询的性能