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 потоков, так что это не так. Он по-прежнему использует 5, даже если я изменю GetPage
, чтобы забить процессор.
Если вам нужно использовать это только для одной конкретной задачи - и вы не возражаете против слегка вонючего кода - вам, честно говоря, лучше всего реализовать его самостоятельно.