【发布时间】:2015-03-04 10:40:18
【问题描述】:
我想知道是否有人想出一种方法来正确处理 JavaFX 8 (jdk 1.8.0_31) WebView 中的超时。问题如下:
假设您有一个
WebView的实例,并告诉它load一个特定的URL。此外,您希望在加载文档后对其进行处理,因此您将侦听器附加到为 Web 视图提供动力的LoadWorker的stateProperty和WebEngine。但是,某个网站在加载过程中超时,导致 stateProperty 转换为Worker.State.RUNNING并一直卡在那里。
然后网络引擎就完全卡住了。我想实现一个检测超时并取消加载的系统。为此,我正在考虑向progressProperty 添加一个侦听器并使用某种形式的Timer。思路如下:
我们在 Web 视图上启动加载请求。超时计时器立即开始运行。在每次进度更新时,计时器都会重置。如果进度达到 100%,则计时器无效并停止。但是,如果计时器结束(因为在某个时间范围内没有进度更新,我们假设超时),加载请求将被取消并引发错误。
有谁知道最好的实现方式吗?
亲切的问候
更新
我制作了一个代码 sn-p,其行为在问题中描述。唯一困扰我的是我无法取消LoadWorker:调用LoadWorker#cancel 挂起(函数永远不会返回)。
public class TimeOutWebEngine implements Runnable{
private final WebEngine engine = new WebEngine();
private ScheduledExecutorService exec;
private ScheduledFuture<?> future;
private long timeOutPeriod;
private TimeUnit timeOutTimeUnit;
public TimeOutWebEngine() {
engine.getLoadWorker().progressProperty().addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
if (future != null) future.cancel(false);
if (newValue.doubleValue() < 1.0) scheduleTimer();
else cleanUp();
});
}
public void load(String s, long timeOutPeriod, TimeUnit timeOutTimeUnit){
this.timeOutPeriod = timeOutPeriod;
this.timeOutTimeUnit = timeOutTimeUnit;
exec = Executors.newSingleThreadScheduledExecutor();
engine.load(s);
}
private void scheduleTimer(){
future = exec.schedule(TimeOutWebEngine.this, timeOutPeriod, timeOutTimeUnit);
}
private void cleanUp(){
future = null;
exec.shutdownNow();
}
@Override
public void run() {
System.err.println("TIMED OUT");
// This function call stalls...
// engine.getLoadWorker().cancel();
cleanUp();
}
}
【问题讨论】:
-
您能否提供导致您问题的网站示例?
-
这当然是一个不稳定的性质,但截至目前,这个网址的加载速度非常慢:northsearegion.eu/ivb/projects/details/…,或者至少对我来说......请注意它最终 加载,但在过去我遇到过导致我的进程“死锁”的实际超时。