{oldActiveCode : oldTime}
и {"1000812001401": 1553503004448}
не совпадают. Первый устанавливает свойство oldActiveCode
, а второй устанавливает свойство 1000812001401
.
Если свойство должно быть 1000812001401
, оно должно быть вычисляемым свойством, {[oldActiveCode] : oldTime}
.
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
ковать ЦП.
Если только необходимо использовать это для одной конкретной задачи - и Вы не возражаете против немного вонючего кода - Вы могли бы быть лучшими от реализации его сами, чтобы быть честными.
По умолчанию .NET имеет предел 2 параллельных соединений к сервисному центру конца (IP:port). Вот почему Вы не видели бы различия, если все URL к одному и тому же серверу.
Этим можно управлять с помощью ServicePointManager. Свойство DefaultPersistentConnectionLimit.
Контролируйте свой сетевой трафик. Если URL от того же домена, он может ограничивать пропускную способность. Больше соединений не могло бы на самом деле обеспечить ускорение.
Я думаю, что уже существуют хорошие ответы на вопрос, но я хотел бы высказать одно важное мнение. Используя PLINQ для задач, которые не являются зависящими от ЦП, в принципе неправильный дизайн. Чтобы не сказать, что это не будет работать - это будет, но использующий несколько потоков, когда это будет ненужным, может доставить неприятности.
Unfortunatelly, нет никакого хорошего способа решить эту проблему в C#. В F# Вы могли использовать асинхронные рабочие процессы, которые работают параллельно, но не блокируют поток при выполнении асинхронных вызовов (под покрытием, это использует BeginOperation
и EndOperation
методы). Можно найти больше информации здесь:
Та же идея может в некоторой степени использоваться в C#, но это выглядит немного странным (но это более эффективно). Я написал статью об этом и существует также библиотека, которая должна быть немного более развита, чем моя исходная идея: