这是一篇老帖子,但我想澄清一些内容:
SwingWorker.get会抛出InterruptedException和ExecutionException作为已检查异常。
另外它还会抛出一个特定的未检查异常CancellationException。当你调用了cancel方法后再试图调用get方法时,就会抛出该异常。虽然可能会抛出其他未检查异常,但CancellationException并不是一个“异常”或者意外的异常。
当doInBackground方法中产生异常时,ExecutedException异常就会被抛出,并且原始异常会被包装在ExecutionException中。当调用get()方法时,将会抛出ExecutionException。提取原始异常并进行管理的想法是好的(正如Emil H指出的那样)。
CancellationException是未检查异常,但我认为它应该是检查异常。API实现没有将其设置为检查异常的唯一借口就是它有一个status方法isCancelled()。你可以采取以下措施:
- 检测isCancelled()方法是否为真,如果是,则不要调用get()方法,因为这会抛出CancellationException。
- 使用try-catch包围get()方法并添加CancellationException,因为它是未检查异常,编译器不会强制要求添加。
- CancellationException未被检查,让你自由地忘记所有这些内容并得到一个惊喜。
- 不取消worker,则可以执行任何操作。
如果使用cancel(true)取消SwingThread,doInBackground中第一个可中断的方法调用(肯定是Thread.sleep,this.wait以及一些IO方法)将会抛出InterruptedException。但是这个异常不会被包装在ExecutionException中。 doInBackground会以中断异常结束。如果它被捕获并转换为其他异常,那么这些异常将被忽略,因为在此时cancel已经在EDT上调用了SwingThread.done,如果done调用了get,则只会得到标准的CancellationException,而不是InterruptedException!
如果使用cancel(false)取消,doInBackground内部不会引发InterruptException异常。如果使用cancel(true),但是doInBackground内没有可中断的方法调用,也不会引发异常。在这些情况下,doInBackground将按其自然循环执行。该循环应该测试isCancelled方法并正常退出。如果doInBackground未这样做,它将永远运行。
我尚未测试是否存在超时,但我不认为会发生。
对我来说,这仍然是一个灰色地带。
在什么情况下get会抛出InterruptedException?我想看一些简短的代码,因为我无法产生类似的异常。 :-)
附言
我在另一个问题&答案中记录了取消时done和state change监听器在doInBackground退出之前被调用的事实。
既然如此,这个-并不是一个错误-在设计doInBackground方法时需要特别注意。如果您对此感兴趣,请参见SwingWorker:何时调用done方法?