JavaFX的任务似乎消耗了异常。它是一个错误还是一个功能?

2022-09-02 01:27:50

请考虑以下代码:

Thread.setDefaultUncaughtExceptionHandler((Thread t, Throwable e) -> {
    System.out.println("An exception occurred!");
});

// set the exception handler for the JavaFX application thread
Thread.currentThread().setUncaughtExceptionHandler((Thread t, Throwable e) -> {
    System.out.println("An exception occurred!");
});

Task<?> task = new Task() {
    @Override
    public Void call() throws Exception {
        throw new RuntimeException("foobar");
    };
};

new Thread(task).start();

如果我们运行代码,运行时异常永远不会触发默认的异常处理程序,而是由任务使用。我发现的抵消这种情况的唯一方法是在 task.setOnFailed 中重新抛出异常:

task.setOnFailed((WorkerStateEvent t) -> {
    throw new RuntimeException(task.getException());
});

既然JavaFX 8现在支持UncaughtExceptionHandler,为什么异常没有传播到异常处理程序呢?


答案 1

在方法内部,只需抛出异常并向任务添加一个,如下所示:Task.call()ChangeListener

task.exceptionProperty().addListener((observable, oldValue, newValue) ->  {
  if(newValue != null) {
    Exception ex = (Exception) newValue;
    ex.printStackTrace();
  }
});

然后,在任务失败并出现异常后,侦听器会通知您在执行期间引发了哪个异常。如果您位于 JavaFX 执行线程中,则可以轻松地将该行与 交换。ex.printStackTrace();Alert


答案 2

功能,任务本身维护属性。这个想法是,当抛出异常时,任务会失败,并且可能会询问抛出了哪个异常。在这方面,Task被设想为一个准批处理作业,在后台运行,并且可能默默地失败。exception

这也反映了一些异步行为;可以处理异常的位置。不在叫开始的地方。


推荐