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

前端之家收集整理的这篇文章主要介绍了c# – 并行Linq – 使用比处理器更多的线程(对于非CPU绑定的任务)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用并行 linq,我正在尝试使用这样的密码下载许多urls:
int threads = 10;
Dictionary<string,string> results = urls.AsParallel( threads ).ToDictionary( url => url,url => GetPage( url );

由于下载网页是网络绑定而不是cpu绑定,使用比我的处理器/核心数更多的线程是非常人为的,因为每个线程的大部分时间都花在等待网络的赶上.然而,判断形式的事实是,使用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;
    }
}

那么这个使用了多少个线程呢?为什么善良知道我有2个处理器,所以不是这样 – 我们已经指定了10个线程,所以不是这样.即使我更改GetPage来敲击cpu仍然使用5.

如果你只需要使用它来处理一个特定的任务 – 而且你不介意稍微有点臭的代码 – 你可能最好不要自己实现,老实说.

猜你在找的C#相关文章