2013-05-12 30 views
1

我试图运行一个后台服务作为我的GUI应用程序的一部分。我正在使用ExecutorService,我从中得到Future。此代码显示我在做什么:Java - 从后台线程传播错误

play.addActionListener(new ActionListener() { 

     service.submit(new Runnable(){ .... } } 
} 

现在,提交正在发生GUI线程,这应该传播异常的主线程上。现在,我不想阻止future.get的主线程,但我宁愿有一些方法来检查未来的结果,以便将异常发布到主线程。有任何想法吗?

回答

0

您可以检查Future.isDone()以查看它是否已完成,或者您可以让后台任务执行操作,例如

play.addActionListener(new ActionListener() { 

    service.submit(new Runnable(){ 
    public void run() { 
     try { 
     // .... 
     } catch(Exception e) { 
      SwingUtils.invokeLater(new Runnable() { 
       public void run() { 
        handleException(e); 
       } 
      } 
     } 
    } 
    }); 
+0

但是'SwingUtilities.invokeLater()'上EDT执行不主线程。 – 2013-05-12 20:03:51

+0

@ Eng.Fouad除非它是OP所讨论的EDT,否则我不知道为什么它需要传递回“主”线程才能执行。 – 2013-05-12 20:06:18

0

你可以有一个额外的线程只是为了监视未来的状态:

final Future<?> future = service.submit(...); 
new Thread(new Runnable() { 
    public void run() { 
     try { 
      future.get(); 
     } catch (ExecutionException e) { 
      runOnFutureException(e.getCause()); 
     } 
    } 
}).start(); 

而且别的地方:

public void runOnFutureException(Exception e) { 
    System.out.println("future returned an exception"); 
} 
+0

如果这样可以,后台线程可以拨打电话。没有必要为此添加另一个线程。 – 2013-05-12 20:07:02

+1

@PeterLawrey肯定 - 它取决于你想把异常混乱的地方 - 我的建议让背景类变得“干净”。但都工作。 – assylias 2013-05-12 20:11:21

1

你可以使用监听器模式时通知后台线程完成。例如,SwingWorker允许PropertyChangeListeners监听SwingWorker.State状态属性,并且可以执行此操作或滚动您自己的属性。这是SwingWorker中我最喜欢的功能之一。

一个例子....

final MySwingWorker mySwingWorker = new MySwingWorker(webPageText); 
    mySwingWorker.addPropertyChangeListener(new PropertyChangeListener() { 

    @Override 
    public void propertyChange(PropertyChangeEvent pcEvt) { 
     if (pcEvt.getNewValue().equals(SwingWorker.StateValue.DONE)) { 
      try { 
       mySwingWorker.get(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); // this needs to be improved 
      } catch (ExecutionException e) { 
       e.printStackTrace(); // this needs to be improved 
      } 
     } 
    } 
    }); 
    mySwingWorker.execute();