我正在构建一个爬虫,我正在使用aBot来完成它.这是一个非常好的系统:)在开发过程中,我发现了一个问题,与我想要构建爬虫的方式有关,而不是aBot项目本身,但我希望你能帮助我.
设置爬网程序时,我指定爬网完成时要调用的方法,有sync和async选项.
crawler.PageCrawlCompleted += crawler_ProcessPageCrawlCompleted;
crawler.PageCrawlCompletedAsync += crawler_ProcessPageCrawlCompleted;
Run Code Online (Sandbox Code Playgroud)
我想使用异步的,因为我会在处理旧的时抓取另一个URL.这工作正常,直到我抓取最后一个网址.当我抓取最后一个时,我调用completeAsync方法并且我的爬虫完成了工作,所以它完成并且程序关闭而没有完全处理_ProcessPageCrawlComplete方法,所以我不能保证最后的URL将被处理.
在关闭申请之前,我有什么方法可以等待最后一次活动结束吗?这是一个设计缺陷吗?
编辑:我忘了提及:我确实可以访问爬虫代码.我目前的解决方法是:如果链接是最后一个要处理的链接,请创建一个WaitHandle并等待它完成.听起来有点乱,但......
ManualResetEvent可以是一个解决方案:
在你的调用方法中:
//Declare the reset event
ManualResetEvent mre = new ManualResetEvent(false);
//Call the async method and subscribe to the event
crawler.PageCrawlCompletedAsync += crawler_ProcessPageCrawlCompleted;
//The application will wait here until the mre is set.
mre.WaitOne();
Run Code Online (Sandbox Code Playgroud)
在事件处理程序中:
private void crawler_ProcessPageCrawlCompleted(...)
{
....
mre.Set();
}
Run Code Online (Sandbox Code Playgroud)
另一种方法可以是CountdownEvent.假设您需要抓取10个页面:
CountdownEvent countdown = new CountdownEvent (10);
//Subscribe to the event
crawler.PageCrawlCompletedAsync += crawler_ProcessPageCrawlCompleted;
//Call 10 time the async method
....
//Wait for all events to complete
countdown.Wait();
Run Code Online (Sandbox Code Playgroud)
在处理程序中:
private void crawler_ProcessPageCrawlCompleted(...)
{
....
mre.Signal();
}
Run Code Online (Sandbox Code Playgroud)