Параллельный процесс интенсивной функции ввода-вывода - PullRequest
3 голосов
/ 12 июня 2011

У меня есть этот пример кода.

List<Dictionary<string,string>> objects = new List<Dictionary<string,string>>();

foreach (string url in urls)
{
    objects.add(processUrl(url))
}

Мне нужно обработать URL, processUrl загрузить страницу и запустить много регулярных выражений, чтобы извлечь некоторую информацию и вернуть объект "C # JSON like", поэтому я хочу запустить это параллельно, и в конце мне нужно список объектов, поэтому мне нужно подождать все задачи, чтобы продолжить процесс, как я могу это сделать? Я вижу много примеров, но ни один из них не спасает возврат.

Привет

Ответы [ 3 ]

2 голосов
/ 12 июня 2011

Как это?

var results = urls.AsParallel().Select(processUrl).ToList();

С Parallel:

Parallel.ForEach(
    urls, 
    url =>
    {
        var result = processUrl(url);
        lock (syncOjbect)
            objects.Add(result);
    };

или

var objects = new ConcurrentBag<Dictionary<string,string>>();
Parallel.ForEach(urls, url => objects.Add(processUrl(url)));
var result = objects.ToList();

или с заданиями:

var tasks = urls
    .Select(url => Task.Factory.StartNew(() => processUrl(url)))
    .ToArray();

Task.WaitAll(tasks);
var restuls = tasks.Select(arg => arg.Result).ToList();
0 голосов
/ 12 июня 2011

Вы можете использовать расширения PLinq, для этого требуется .NET 4.0

System.Threading.Tasks.Parallel
          .ForEach(urls, url => {
             var result = processUrl(url);
             lock(objects)
             {
                  objects.Add(result);
             }
           });
0 голосов
/ 12 июня 2011

Сначала сделайте рефакторинг как

processUrl(url, objects);

и возьмите задачу за добавление результатов в список.

Затем добавьте блокировку, чтобы две параллельные задачи не пытались использовать результатысписок в одно и то же время.


Примечание: поддержка async в следующей версии .NET упростит эту задачу.

...