在.net 4.0中并行化Web爬网程序的最佳实践

时间:2012-05-21 15:43:40

标签: c# web-crawler

我需要通过代理下载大量页面。 构建多线程Web爬网程序的最佳实践是什么?

是Parallel.For \ Foreach是否足够好,还是更适合繁重的CPU任务?

您对以下代码有什么看法?

var multyProxy = new MultyProxy();

   multyProxy.LoadProxyList();


   Task[] taskArray = new Task[1000];

        for(int i = 0; i < taskArray.Length; i++)
        {
            taskArray[i] = new Task( (obj) =>
                {                                                             
                       multyProxy.GetPage((string)obj);
                },

            (object)"http://google.com"
            );
            taskArray[i].Start();
        }


   Task.WaitAll(taskArray);

它的工作非常糟糕。这很慢,我不知道为什么。

这段代码也很糟糕。

 System.Threading.Tasks.Parallel.For(0,1000, new System.Threading.Tasks.ParallelOptions(){MaxDegreeOfParallelism=30},loop =>
            {
                 multyProxy.GetPage("http://google.com");
            }
            );

我觉得我做错了。

当我启动脚本时,它仅使用2%-4%的网络。

3 个答案:

答案 0 :(得分:8)

你基本上是在为IO绑定任务使用CPU绑定线程 - 即。即使您正在并行化您的操作,它们仍然主要使用ThreadPool线程,主要用于CPU绑定操作。

基本上,您需要使用异步模式下载数据以将其更改为使用IO完成端口 - 如果您使用的是WebRequest,那么BeginGetResponse()和EndGetResponse()方法

我建议查看Reactive Extensions来执行此操作,例如:

IEnumerable<string> urls = ... get your urls here...;
var results = from url in urls.ToObservable()
             let req = WebRequest.Create(url)
             from rsp in Observable.FromAsyncPattern<WebResponse>(
                  req.BeginGetResponse, req.EndGetResponse)()
             select ExtractResponse(rsp);

其中ExtractResponse可能只是使用StreamReader.ReadToEnd来获取字符串结果,如果这就是你所追求的

您还可以查看使用.Retry运算符,如果您遇到连接问题等,这将很容易让您重试几次......

答案 1 :(得分:1)

在主方法的开头添加:

System.Net.ServicePointManager.DefaultConnectionLimit = 100;

因此,您不会局限于少量的并发连接。

答案 2 :(得分:0)

当您使用大量连接时,这可能对您有所帮助(添加到app.config或web.config):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.net>
    <connectionManagement>
      <add address="*" maxconnection="50"/>
    </connectionManagement>
  </system.net>
</configuration>

设置并发连接数而不是50

http://msdn.microsoft.com/en-us/library/fb6y0fyc.aspx

了解详情