如何在关闭应用程序之前等待异步事件完成?

JSB*_*ach 1 c#

我正在构建一个爬虫,我正在使用aBot来完成它.这是一个非常好的系统:)在开发过程中,我发现了一个问题,与我想要构建爬虫的方式有关,而不是aBot项目本身,但我希望你能帮助我.

设置爬网程序时,我指定爬网完成时要调用的方法,有sync和async选项.

        crawler.PageCrawlCompleted += crawler_ProcessPageCrawlCompleted;
        crawler.PageCrawlCompletedAsync += crawler_ProcessPageCrawlCompleted;
Run Code Online (Sandbox Code Playgroud)

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

在关闭申请之前,我有什么方法可以等待最后一次活动结束吗?这是一个设计缺陷吗?

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

Alb*_*rto 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();
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)