如何在 RxJava2 中正确释放资源?



我正在使用Selenium和ChromeDriver用Java编写一个抓取工具,我想将其包装到Observable中(以便于异步(。这是从我的解析器类返回 Observable 的代码:

return Observable.interval(5000, 5000, TimeUnit.MILLISECONDS)
.doOnSubscribe(ignored -> initialize())
.doOnNext(ignored -> refreshPage())
.map(ignored -> getHtml())
.map(this::parse)
.flatMap(Observable::fromIterable)
.doFinally(() -> finish())
.share();

所以在这里,initialize()基本上创建了一个Selenium WebDriver的配置实例,refreshPage()重新加载页面并等待它加载,getHtml()只是driver.getPageSource()finish()driver.quit()其中driver是Selenium WebDriver的实例。我遇到的问题是当我订阅这个可观察的并在以后处理它时。我从refreshPage()中得到一个例外,说我在driver.quit()之后driver调用了一个方法(或者在上面的代码中,这意味着refreshPage()是在finish()之后调用的(。

我应该如何创建/修改我的源可观察,以便在处置时正确释放我的资源?(我希望finish()始终在可观察链中的其他所有内容完成后调用(。

更新: 我的finish()函数是:

public void finish() {
driver.quit();
}
doFinally

按照你的怀疑去做。 它在以下之后执行关联的Action

  • onError
  • onComplete
  • 关联的下游取消/处置流

但是,我怀疑可能发生的情况是,您可能在finish()的主体中调用driver.quit(),而不是在它返回的Action中调用。 假设driverrefreshPage()中使用,该错误是有意义的,因为doFinally()本身的实际调用(而不是它返回Action(是尽早完成的,以构建流行为,refreshPage()是此后流中使用driver的最早点。

如果您的代码如下所示:

private Action finish() {
driver.quit();
return () -> {
...
};
}

。然后将调用移动到quit()移动到Action体内,例如:

private Action finish() {
return () -> {
driver.quit();
};
}

如果我的假设是错误的,你能用finish()的代码更新问题吗? 我很想知道那里发生了什么。

相关内容

  • 没有找到相关文章

最新更新