1

我正在构建一个爬虫,我正在使用aBot来完成它。这是一个非常好的系统:) 在开发过程中,我发现一个问题与我想如何构建我的爬虫比 aBot 项目本身更相关,但我希望你能帮助我。

设置爬虫时,我指定爬取完成时调用的方法,有同步和异步选项。

        crawler.PageCrawlCompleted += crawler_ProcessPageCrawlCompleted;
        crawler.PageCrawlCompletedAsync += crawler_ProcessPageCrawlCompleted;

我想使用异步的,因为那样我会在处理旧的网址时抓取另一个网址。这工作正常,直到我抓取最后一个网址。当我爬取最后一个时,我调用了 completeAsync 方法,我的爬虫已经完成工作,所以它完成并关闭了程序而没有完全处理完 _ProcessPageCrawlComplete 方法,所以我不能保证最后一个 url 会被处理。

有什么办法可以在关闭应用程序之前等待最后一个事件完成?这是设计缺陷吗?

编辑:我忘了提:我确实可以访问爬虫代码。我目前的解决方法是:如果链接是最后一个要处理的链接,则创建一个 WaitHandle 并等待它完成。听起来有点乱,虽然...

4

1 回答 1

5

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();

在您的事件处理程序中:

private void crawler_ProcessPageCrawlCompleted(...)
{
   ....
   mre.Set();
}

另一种方法可以是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();

在处理程序中:

private void crawler_ProcessPageCrawlCompleted(...)
{
    ....
   mre.Signal();
}
于 2013-11-06T15:07:35.943 回答