java - 使用 SwingWorker 时应该如何处理异常?

标签 java swing swingworker

我在 Java 6 中使用 SwingWorker 以避免在事件调度线程上运行长时间运行的代码。

如果在我的 done() 方法中调用 get() 返回异常,那么处理异常的适当方法是什么?

我特别担心可能的 InterruptedExceptions。 JavaDoc 示例只是忽略了异常,但多年来我了解到吞下异常会导致难以调试的代码。

示例用法如下:

new SwingWorker<String, Void>() {

    @Override
    protected String doInBackground() throws Exception {
        // do long-running calculation
        return result;
    }

    @Override
    protected void done() {
        try {
            setTextField(get());
        } catch (InterruptedException e) {
            e.printStackTrace();  
        } catch (ExecutionException e) {
            e.printStackTrace();  
        }
    }
}.execute();

最佳答案

这是一篇旧帖子,但我想澄清一下:

SwingWorker.get 抛出 InterruptedException、ExecutionException 作为检查异常。

此外,它还会引发一个非常具体的未经检查的异常,即 CancellationException。 当然,它可能会抛出任何未经检查的异常,但 CancellationException 不是“异常”和意外的异常。当您在调用取消之后尝试调用 get 方法时会抛出它。

当在 doInBackground 中抛出异常时会抛出 ExecutedException。 原始异常包含在 ExecutionException 中。 当调用 get() 方法时,将抛出 ExecutionException。 取出原始异常并进行管理的想法很好。 (正如 Emil H 指出的那样)。

CancellationException 未选中,我认为应该选中。 API 实现不检查它的唯一借口是它有一个状态方法 isCancelled()。
您可以:
- 测试 isCancelled(),如果为真,则不要调用 get(),因为它会抛出 CancellationException
- 用 try-catch 包围 get() 并添加 CancellationException,因为编译器不会要求未检查的情况
- 取消检查 CancellationException 的事实让您可以自由地忘记所有这些东西并获得惊喜。
- 做任何事情,因为你不会取消 worker

中断异常。如果使用 cancel(true) 取消 SwingThread,doInBackground 中的第一个可中断方法调用(肯定是 Thread.sleep、this.wait,可能还有一些 IO 方法)将抛出 InterruptException。但是这个异常没有包含在 ExecuteException 中。 doInBackground 将因异常中断而终止。如果它被捕获并转换为其他异常,则这些异常将被忽略,因为此时 cancel 已经在 EDT 上调用了 SwingThread.done,如果 done 调用了 get,它只得到标准的 CancellationException。 不是 InterruptedException!

如果您使用 cancel(false) 取消,则不会在 doInBackground 中引发 InterruptException。 如果您使用 cancel(true) 取消但在 doInBackground 中没有可中断的方法调用,则相同。 在这些情况下,doInBackground 将遵循其自然循环。此循环应测试 isCancelled 方法并正常退出。 如果 doInBackground 不这样做,它将永远运行。 我没有测试过是否存在超时,但我不这么认为。

对我来说,它仍然只是一个灰色地带。 哪些情况下get会抛出InterruptedException?我想看一些简短的代码,因为我无法产生类似的异常。 :-)

附: 我在另一个 Question&Answer 中记录了在 doInBackground 退出之前调用完成和状态更改监听器以防取消。 既然这是真的,那么在设计 doInBackground 方法时,这不是一个错误,需要特别注意。如果您对此感兴趣,请参阅 SwingWorker: when exactly is called done method?

关于java - 使用 SwingWorker 时应该如何处理异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/791223/

相关文章:

java - 绘制像素时数组索引越界

java - 我怎样才能最好地在 Swing 中实现淡入淡出按钮效果?

java - 使用 SwingWorker 实现 UDP 客户端/服务器

java - Nashorn 中新的 Java 字符串数组

java - 让我的 ActionListeners、Handlers 和 GUI 进行通信时遇到问题

java - 顶部带有 JComponents 的动画

java - 我应该在哪里以 Java MVC 模式调用我的 swingworker

java - RabbitMQ 集群镜像队列行为

java - 从键盘获取输入时变量获取未知值

Java JTextArea - 添加换行符