我最近继承了一些遗留代码,这些代码大量使用内部类来实现线程。这些内部类使当前JFrame
代码成为整体,因此我正在重构代码以利用SwingWorker
该类。
我的SwingWorker
班级对 Web 服务进行了多次 API 调用,然后返回结果。由于这是异步的,这显然最好在线程内完成。目前,Web 服务的工作方式需要一些身份验证调用来验证请求。这些调用显然会返回错误。SwingWorker
如果这些 Web 服务调用未通过身份验证,我想做的是从内部抛出一个自定义异常。使用标准Future
模式,我的代码类似于以下内容:
SwingWorker(后台线程)
@Override
protected String doInBackground() throws Exception {
if (!authenticationClient.authenticate(userid)) {
throw new PlaceOrderException("Failed to authenticate client");
}
return orderClient.placeOrder( ... );
}
主 GUI(EDT 线程)
// On the EDT
PlaceOrderWorker placeOrderWorker = new PlaceOrderWorker( ... ) {
// This method is invoked when the worker is finished its task
@Override
protected void done(){
try {
String orderID = get();
// Update some GUI elements using the orderID
} catch(PlaceOrderException e) {
JOptionPane.showMessageDialog(this, "Please review your order", e.getMessage(), JOptionPane.ERROR_MESSAGE, null);
} catch (Exception e) {
LOGGER.error("Error placing order", e);
}
}
}
错误发生在该行:
catch(PlaceOrderException e) {
JOptionPane.showMessageDialog(this, "Please review your order", e.getMessage(), JOptionPane.ERROR_MESSAGE, null);
}
正如 Java 声称的那样,这个异常永远不会被抛出。
exception PlaceOrderException is never thrown in body of corresponding try statement
现在我知道调用get
会导致异常从线程中重新抛出 - 它可以抛出一个PlaceOrderException
. 我怎样才能捕捉到这个特定的异常?我这样构造我的代码的原因是有许多异常可以在后台线程中抛出,我希望用户通过JDialog
. 我在主 GUI 类中声明该done
方法的原因是我需要JDialog
从 EDT 线程中实例化 s。这让我有一些很好的解耦。
任何人都知道我使用 using 捕获此特定异常的方法instanceof
吗?或者你能推荐一个更好的模式来使用吗?也许SwingWorker
是错误的选择?