【问题标题】:How do I wait for a SwingWorker's doInBackground() method?如何等待 SwingWorker 的 doInBackground() 方法?
【发布时间】:2011-05-14 18:48:24
【问题描述】:

假设我有以下代码:

import java.lang.InterruptedException;
import javax.swing.SwingWorker;

public class Test
{
    private JDialog window;

    public Test
    {
        // instantiate window
    }

    private class Task extends SwingWorker<Void, Void>
    {
        public Void doInBackground()
        {
            try { Thread.currentThread().sleep(5000); }
            catch(InterruptedException e) {}
            return null;
        }
    }

    public void doTask()
    {
        Task task = new Task();
        task.execute();
    }

    protected void process()
    {
        // update various GUI components here
    }

    public static void main(String args[])
    {
        Test t = new Test();
        t.doTask();
        System.out.println("done");
    }
}

我需要等到t.doTask() 完成后才能打印出“完成”,但我不确定具体如何操作。我知道我可能应该在这里使用join(),但是我需要一个线程来调用它,而且我不知道如何从我需要调用join() 的地方获取doInBackground() 的线程。感谢您的帮助。


编辑:感谢您的回复。不幸的是,get() 等并不能完全解决问题。在我的实际代码中,SwingWorker 还有一个被覆盖的process() 函数,它在后台线程运行时更新GUI 窗口。 get() 确实停止打印“完成”,直到 doInBackground 之后,但随后 GUI 不会更新。我更新了我的示例代码以反映这一点,尽管现在它当然不会编译。

有没有办法在doInBackground 完成后才“完成”打印? GUI 更新代码和“完成”语句是否在同一个线程上?我需要创建一个新线程吗?

【问题讨论】:

    标签: java swing synchronization swingworker


    【解决方案1】:

    通常,在 SwingWorker 完成其后台工作后需要完成的任何事情都是通过覆盖其中的 done() 方法来完成的。完成后在 Swing 事件线程上调用此方法,允许您更新 GUI 或打印一些内容或其他内容。如果您确实需要阻止直到完成,您可以致电get()

    注意。在done() 方法中调用get() 将立即返回您的结果,因此您不必担心会阻塞任何UI 工作。

    【讨论】:

    【解决方案2】:

    您可以覆盖 done() 方法,该方法在 doInBackground() 完成时调用。在 EDT 上调用 done() 方法。所以像:

    @Override
    protected void done() {
      try {
        super.get();
    
        System.out.println("done");
        //can call other gui update code here
      } catch (Throwable t) {
        //do something with the exception
      }
    }
    

    在 done 中调用 get() 方法有助于恢复在 doInBackground 期间抛出的任何异常,因此我强烈推荐它。 SwingWorker 在内部使用 Callable 和 Future 来管理后台线程,您可能需要阅读这些线程而不是尝试加入/屈服方法。

    【讨论】:

    • 应该对 Colin D 的回答发表评论。
    【解决方案3】:

    一般情况下,您必须按住SwingWorker 直到它完成,您可以通过调用isDone() 对其进行测试。否则,只需调用 get() 即可等待。

    【讨论】:

      【解决方案4】:

      调用get() 将导致SwingWorker 阻塞。

      来自 Javadocs:

      T get() 
            Waits if necessary for the computation to complete, 
            and then retrieves its result.
      

      您的代码将如下所示:

      public static void main(String args[])
      {
          Test t = new Test();
          t.doTask();
          t.get();  // Will block
          System.out.println("done");
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-07
        • 2011-12-28
        • 2012-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多