这是一个旧帖子,但我想澄清一下:
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 未被选中,让您可以忘掉所有这些东西并获得惊喜。
- 做任何事情,因为你不会取消工人
中断异常。如果使用 cancel(true) 取消 SwingThread,doInBackground 中的第一个可中断方法调用(肯定是 Thread.sleep、this.wait,可能还有一些 IO 方法)将抛出 InterruptException。但是这个异常没有包含在 ExecuteException 中。doInBackground 将因异常中断而终止。如果它被捕获并转换为其他异常,则这些异常将被忽略,因为此时 cancel 已经在 EDT 上调用了 SwingThread.done,如果 done 调用了 get,它只得到标准的 CancellationException。不是中断异常!
如果使用 cancel(false) 取消,则不会在 doInBackground 中引发 InterruptException。如果您使用 cancel(true) 取消但在 doInBackground 中没有可中断的方法调用,则相同。在这些情况下,doInBackground 将遵循其自然循环。此循环应测试 isCancelled 方法并正常退出。如果 doInBackground 不这样做,它将永远运行。我没有测试过是否存在超时,但我不这么认为。
对我来说,它仍然只是一个灰色地带。哪些情况下get会抛出InterruptedException?我想看一些简短的代码,因为我无法产生类似的异常。:-)
PS 我在另一个 Question&Answer 中记录了在 doInBackground 退出之前调用完成和状态更改侦听器以防取消。既然这是真的,那么在设计 doInBackground 方法时,这不是一个错误,需要特别注意。如果您对此感兴趣,请参阅SwingWorker:何时调用 done 方法?