3

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

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% 使用网络。

4

3 回答 3

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 运算符,如果遇到连接问题等,您可以轻松地重试几次......

于 2012-05-21T15:56:57.143 回答
1

在 main 方法的开头添加:

System.Net.ServicePointManager.DefaultConnectionLimit = 100;

因此,您将不会受到少量并发连接的限制。

于 2012-05-21T15:51:30.763 回答
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了解更多信息

于 2012-05-21T15:50:06.400 回答