通过BackgroundWorker 组件从 Web 下载许多页面

本文关键字:下载 许多页 Web BackgroundWorker 组件 通过 | 更新日期: 2023-09-27 18:32:50

我有很多网址(大约800个(可以从网上下载。我有一个类:HttpDownloader.cs它与HttpWebRequest类一起使用来下载和获取html页面。之后,我按正则表达式对页面进行分段。

我想使用后台工人组件,但我不知道如何对所有页面执行此操作。 通过循环,或类似的东西。

我的代码:

我尝试使用ThreadPool,它确实存在问题。我尝试了 4 个网址,但它不起作用。

      foreach (string link in MyListOfUrls)
      {
 ThreadPool.QueueUserWorkItem((o) => {
           HttpDownloader httpDownload = new HttpDownloader(link);
           string htmlDoc = httpDownload.GetPage();//get the html of the page 
           HtmlDocument doc=doc.LoadHtml(htmlDoc);//load html string to doc for pharsing
           DoPharsing();//my func for pharsing
           Save();//save into dataBase
  });
      }

因为我在我的函数中使用了与数据库和数据表的连接,所以当我使用 ThreadPool 时,我得到一个异常:

"函数评估

已禁用,因为以前的函数评估 已超时。您必须继续执行才能重新启用函数 评价。

因此,我无法从数据表中获取数据。 也许我需要下载所有内容,然后进行分段并保存??

如何通过后台工作者组件将其更改为异步?

附言不要建议我使用异步 Tpc,因为我无法下载它。

谢谢

通过BackgroundWorker 组件从 Web 下载许多页面

这取决于您要拆分的内容,整个循环或仅循环的下载部分。显然,如果您希望整个循环在后台进行,那么最简单的方法就是使用 ThreadPool。

请注意,您可能需要更改解析和保存函数,以便将 HTML 文档传递给每个函数。

ThreadPool.QueueUserWorkItem((o) => {
  foreach (string link in MyListOfUrls)
  {
    HttpDownloader httpDownload = new HttpDownloader(link);
    string htmlDoc = httpDownload.GetPage();//get the html of the page
    HtmlDocument doc=doc.LoadHtml(htmlDoc);//load html string to doc for pharsing
    var result = DoPharsing(doc);//my func for pharsing
    Save(result);//save into dataBase
 } 
});

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (o, e) => { 
  foreach (string link in MyListOfUrls)
  {
    HttpDownloader httpDownload = new HttpDownloader(link);
    string htmlDoc = httpDownload.GetPage();//get the html of the page
    HtmlDocument doc=doc.LoadHtml(htmlDoc);//load html string to doc for pharsing
    var result = DoPharsing(doc);//my func for pharsing
    Save(result);//save into dataBase
 } 
};
worker.RunWorkerCompleted += (o, e) => {
   // Job completed
}
worker.RunWorkerAsync();

要同时下载多个链接,只需切换创建线程的位置。

foreach (string link in MyListOfUrls)
{
  ThreadPool.QueueUserWorkItem((o) => {
    HttpDownloader httpDownload = new HttpDownloader(link);
    string htmlDoc = httpDownload.GetPage();//get the html of the page
    HtmlDocument doc=doc.LoadHtml(htmlDoc);//load html string to doc for pharsing
    var result = DoPharsing(doc);//my func for pharsing
    Save(result);//save into dataBase
  });
 } 

(我认为这里的线程池比创建数百个后台工作者更好(。

我最终找到了答案
这是我的代码:

static BackgroundWorker[] d=new BackgroundWorker[MyListOfUrls.Length];
  string html=new string[MyListOfUrls.Length]
  static void Main(string[] args)
  {
    for (int i = 0; i < MyListOfUrls.Length; i++)
    {
         d[i]=new BackgroundWorker{WorkerReportsProgress=true};
         d[i].DoWork += new DoWorkEventHandler(worker2_DoWork);
         d[i].ProgressChanged += new ProgressChangedEventHandler(Program_ProgressChanged);
         d[i].RunWorkerAsync(i);
         d[i].RunWorkerCompleted += new RunWorkerCompletedEventHandler(RunWorkerCompleted);
         Thread.Sleep(1000);
    }
  }  
  static void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  {
      Console.WriteLine("End");
  }
  static void Program_ProgressChanged(object sender, ProgressChangedEventArgs e)
  {
      Console.WriteLine(e.ProgressPercentage.ToString());
  }
  static void worker2_DoWork(object sender, DoWorkEventArgs e)
  {
      var worker = (BackgroundWorker)sender;
      worker.ReportProgress((int)e.Argument);
      HttpDownloader httpDownload = new HttpDownloader(link);
      html[(int)e.Argument] = httpDownload.GetPage();
      Thread.Sleep(500);
  }

如果有人知道如何做得更好,我会很高兴。他克斯,查尼