C# 并行处理是一种密集的IO功能
我有这个示例代码C# 并行处理是一种密集的IO功能,c#,parallel-processing,task-parallel-library,webresponse,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)) } List objects=newlist(); foreach(url中的字符串url) { 添加(processUrl(url)) }
List<Dictionary<string,string>> objects = new List<Dictionary<string,string>>();
foreach (string url in urls)
{
objects.add(processUrl(url))
}
List objects=newlist();
foreach(url中的字符串url)
{
添加(processUrl(url))
}
我需要处理URL,processUrl
下载页面并运行许多正则表达式来提取一些信息并返回一个“类似于C#JSON”的对象,所以我想并行运行,最后我需要一个对象列表,所以我需要等待所有任务继续处理,我如何才能完成这个任务?我举了很多例子,但没有一个能保存回报
首先,将重构视为
processUrl(url, objects);
并让任务负责将结果添加到列表中
然后添加锁定,这样两个并行任务就不会试图同时使用结果列表
注意:
async
在下一版本的.NET中的支持将使这变得非常简单。像这样吗
var results = urls.AsParallel().Select(processUrl).ToList();
与并行时
:
Parallel.ForEach(
urls,
url =>
{
var result = processUrl(url);
lock (syncOjbect)
objects.Add(result);
};
或
您可以使用PLinq扩展,这需要.NET 4.0
System.Threading.Tasks.Parallel
.ForEach(urls, url => {
var result = processUrl(url);
lock(objects)
{
objects.Add(result);
}
});
只要项目位于类似列表的集合中(例如数组或
列表
),就可以使用Parallel.For。然后可以使用循环索引将结果输出到数组槽中。这将是线程安全的,不需要锁。我不会在Parallel.ForEach的主体中使用锁,而是使用具有localInit
和localFinally
的重载,并在localFinally中聚合所有结果。这样,您就不会锁定每个操作,每个线程只锁定一次。在localInit中放置一个空列表,在不锁定正文的情况下添加到local,然后最终收集。所有这些选项都无法限制同时执行任务的总数。@Rick Sladkey-我不确定是否理解您的评论。这三个选项都有限制同时执行任务数量的方法,我没有在代码中说明,因为没有人问过。我只是警告大家在启动一千个线程之前要小心。@Rick Sladkey-实际上,默认情况下,这些方法都不会启动太多线程。作出线程或等待的决定是由调度程序做出的,默认情况下,它将基于CPU内核数和线程等待数。相反,若您想用这种方法启动无限数量的线程,这将是一个问题。然而,如果您使用Task
方法,它也是可以解决的。
var tasks = urls
.Select(url => Task.Factory.StartNew(() => processUrl(url)))
.ToArray();
Task.WaitAll(tasks);
var restuls = tasks.Select(arg => arg.Result).ToList();
System.Threading.Tasks.Parallel
.ForEach(urls, url => {
var result = processUrl(url);
lock(objects)
{
objects.Add(result);
}
});