通过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,因为我无法下载它。
谢谢
这取决于您要拆分的内容,整个循环或仅循环的下载部分。显然,如果您希望整个循环在后台进行,那么最简单的方法就是使用 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);
}
如果有人知道如何做得更好,我会很高兴。他克斯,查尼