使用SwingWorker时如何处理异常? [英] How should I handle exceptions when using SwingWorker?

查看:186
本文介绍了使用SwingWorker时如何处理异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I use SwingWorker in Java 6 to avoid running long-running code on the event dispatch thread.

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

If the call to get() in my done() method returns an exception, what is an appropriate way of handling the exception?

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

I'm particularly concerned about possible InterruptedExceptions. The JavaDoc example simply ignores the exception but I've learnt over the years that swallowing exceptions leads to hard-to-debug code.

示例用法如下:

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();


推荐答案

这是一个老帖子,但我想做一些澄清:

It's an old post, but I want to do some clarification:

SwingWorker.get抛出InterruptedException,ExecutionException作为已检查的异常。

SwingWorker.get throws InterruptedException, ExecutionException as checked exceptions.

另外它抛出一个非常具体的未选中例外是CancellationException。
当然它可能会抛出任何未经检查的异常,但CancellationException不是一个例外和意外的异常。在尝试调用get方法之后调用它时抛出它。

Plus it throws a very specific unchecked exception that is CancellationException. Of course it could potentially throw any unchecked exception, but CancellationException is not an "exceptional" and unexpected one. It is thrown when you try to call get method after that has been called cancel.

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

ExecutedException is thrown when an Exception is thrown inside doInBackground. The original exception is wrapped inside an ExecutionException. When the get() method will be called, the ExecutionException will be thrown. The idea of take out the original exception and manage that is good. (As Emil H pointed out).

取消取消取消,我认为应该检查。
API实现的唯一借口是不要检查它是否有状态方法isCancelled()。

你可以:

- test isCancelled( )如果为true则不调用get(),因为它会抛出CancellationException

- 使用try-catch环绕get()并添加CancellationException,因为unchecked不会被编译器请求

- 未选中CancellationException的事实让您可以自由地忘记所有这些并获得惊喜。

- 做任何事情,因为你不会取消工人?

CancellationException is unchecked and in my opinion should be checked. The only excuse for the API implementation not to have it as checked is that it has a status method isCancelled().
You can either:
- test isCancelled() and if is true do NOT call get() since it will throw CancellationException
- surround get() with try-catch and add the CancellationException, that since unchecked will not requested by compiler
- the fact that CancellationException is not checked leave you free to forget all that stuff and get a nice surprise.
- do anything because you won't cancel the worker

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

InterruptedException. If you cancel a SwingThread with cancel(true) the first interruptable method call (for sure Thread.sleep, this.wait, maybe some IO methods) in doInBackground will throw InterruptException. But this exception is not wrapped in an ExecuteException. The doInBackground is left to terminate with interrupted exception. If it is catched and converted to some other exception, those will be ignored because by this moment cancel has already invoked SwingThread.done on the EDT, and if done has called get, it has get just the standard CancellationException. Not an InterruptedException!

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

If you cancel with cancel(false) no InterruptException is raised inside doInBackground. The same if you cancel with cancel(true) but there are no interruptable method calls inside doInBackground. In these cases, the doInBackground will follow its natural loop. This loop should test the isCancelled method and exit gracefully. If the doInBackground doesn't do so, it will run forever. I've not tested for the presence of timeouts, but I not belive so.

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

For me, it remains just a gray area. In which cases is InterruptedException thrown by get? I'd like to see some short code, since I couldn't produce a similar exception. :-)

P.S。
我在另一个问题和答案中记录了在doInBackground退出之前调用了取消时的完成和状态更改侦听器。
因为这是真的,这不是一个错误 - 在设计doInBackground方法时需要特别注意。如果您对此感兴趣,请参阅 SwingWorker:何时称为完成方法?

这篇关于使用SwingWorker时如何处理异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆