java - SwingWorker 的 done 方法甚至在 doInBackground 完成之前随机执行

标签 java multithreading swing swingworker

我有一 block JFrame代码,停止 SwingWorker关闭时:

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.SwingWorker;
import javax.swing.WindowConstants;

/**
 *
 * @author yccheok
 */
public class JavaApplication11 extends JFrame {

    public JavaApplication11() {
        this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        final Task task = new Task();
        task.execute();
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent e) {
                if (task != null) {
                    task.cancel(true);
                }
            }           
        }); 
    }

    public class Task extends SwingWorker<Void, Void> {

        @Override
        protected Void doInBackground() {
            for (int i = 0; i < 1000; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    System.out.println("interrupted in doInBackground");
                    break;
                }
                System.out.println("-> " + i);
            }
            return null;
        }

        @Override
        public void done() {
            System.out.println("DONE!!!");
        }        
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new JavaApplication11().setVisible(true);
    }
}

但是,随机地,我在关闭 JFrame 时意识到, SwingWorkerdone方法在 doInBackground 之前执行完成了。 (需要多次执行上面的JFrame才能产生问题)

-> 0
-> 1
-> 2
-> 3
-> 4
DONE!!!
interrupted in doInBackground

请问这是为什么?

最佳答案

来自霍华德的评论,http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6826514表明这可能是一个错误。

我也遇到过这个问题。我倾向于把清理放在里面 doInBackground ,如果它依赖于顺序,并且只使用 done用于异常处理。

@Override
protected Void doInBackground() {
    try {
        // ...
    } finally {
        // some cleanup inside 'doInBackground'
        if (isCancelled()) {
            // ...
        } else {
            // ...
        }
    }
    return (Void) null;
}
@Override
protected void done() {
    try {
        get();
    } catch (CancellationException x) {
        // ...
    } catch (InterruptedException x) {
        // ...
    } catch (ExecutionException x) {
        // ...
    }
}

(如果您需要从 invokeLater 更新 GUI,请记住使用 doInBackground。)

在我的例子中,我有这样的事情:

  • doInBackground执行“打开文件”例程,定期创建 Swing 组件并将它们添加到 GUI。
  • 关于取消(通过带有取消 按钮的进度条对话框),done将删除在 doInBackground 期间创建的所有组件.

有时这些 Action 会重叠,并且doInBackground将在 done 之后继续创建组件执行了删除。对于用户来说,似乎按 Cancel 只是偶尔不起作用,除了调试显示 done。被召唤。除了 SwingWorker 的这种行为外,没有其他解释。 .

关于java - SwingWorker 的 done 方法甚至在 doInBackground 完成之前随机执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18778587/

相关文章:

java - Apache Tomcat 无法加载 Mysql 驱动程序

java - 在运行时,如何限制java线程的数量

Java 1.6 Graphics2D : Rendering text into a box

java - 如何使用 poi 从 xlsx 文件中删除公式?

java - Talend Server 外部 Jar 文件

java - 如何解决各种 log4j 的包冲突?

multithreading - 如何将纤维传递给线程?

ruby-on-rails - 在 ruby​​ 中通过并行处理有序插入数据

java - 如何保持 JTabe 窗口的焦点直到用户响应?

java - 有没有办法使用 JfileChooser 中选择的扩展名来保存 bufferedImage?