并行处理密集的IO功能

时间:2011-06-12 02:05:16

标签: c# parallel-processing task-parallel-library webresponse

我有这个示例代码。

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 个答案:

答案 0 :(得分:2)

喜欢这个吗?

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();

答案 1 :(得分:0)

首先,重构为

processUrl(url, objects);

并使任务负责将结果添加到列表中。

然后添加锁定,这样两个并行任务就不会尝试在完全相同的时间使用结果列表。


注意:在下一版本的.NET中,async支持将使这一切变得简单。

答案 2 :(得分:-1)

您可以使用PLinq扩展,这需要.NET 4.0

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