【问题标题】:Why does WindowClosing handler not execute Background Tasks before exiting program?为什么 WindowClosing 处理程序在退出程序之前不执行后台任务?
【发布时间】:2013-03-20 03:40:45
【问题描述】:
mainFrame().addWindowListener(new java.awt.event.WindowAdapter() {
    @Override
    public void windowClosing(java.awt.event.WindowEvent evt)
    {
        retrieveItems();
        closeAllConnections();
        System.exit(0);
    }
});

对于上面的代码,retrieveItems() 执行得很好,但是在 closeAllConnections() 内部有一个名为 doBackup() 的后台任务根本不执行。该程序似乎只是跳过了任务。以下是closeAllConnections() 包含的内容的简要视图;

public void closeAllConnections()
{
    boolean shouldBackup = getBackupOnCloseStatus();
    if(shouldBackup)
    {
        doBackUp();
    }
    dbManager.disconnectDB();
}

使用Netbeans Step-Debugger 后,我注意到程序执行甚至没有进入doBackup() 方法,就在应用程序退出之前。这很奇怪。对于可能导致这种行为的任何帮助,我将不胜感激。谢谢好心人!

如果这条额外的信息可能有助于找到解决方案,我正在使用 Swing 应用程序框架,所以任务 doBackup() 看起来像以下...

@Action
public Task doBackUp()
{
    return new DoBackUpTask(getApplication());
}

private class DoBackUpTask extends org.jdesktop.application.Task<Object, Void> 
{
    private boolean done = false;

    DoBackUpTask(org.jdesktop.application.Application app) 
    {
        super(app);
        this.setMessage("Backing-up database...");
    }

    @Override 
    protected Object doInBackground() 
    {
        File destDir = new File(appManager.getBackUpDir());
        done = backUpDataBase(destDir);
        return null;
    }

    @Override 
    protected void succeeded(Object result) 
    {
        if(done)
        {
            setMessage("BackUp completed.");
        }
    }
}

【问题讨论】:

  • 你是否在任何地方设置了JFrame的默认关闭操作?
  • 我会说是因为你在DoBackUpTask可以执行之前调用了System.exit(0)(假设它是一个非守护线程)
  • @HovercraftFullOfEels 我没有明确设置默认关闭操作...但我怀疑 Netbeans GUI-Builder 可能在应用程序的 mainFrame ('FrameView' in SAF 的情况)使用“X”按钮关闭。
  • @MadProgrammer,我认为您可能是对的,但我无法找到 netbeans GUI-Builder 在主 FrameView 上设置关闭操作的位置。它在 JDialogs 上比在这些 SAF FrameViews 上更容易找到
  • @Teejay 也许你可以改用shut down hook

标签: java awt windowlistener background-thread swing-app-framework


【解决方案1】:

我的猜测是您在其他地方有另一个 WindowListener 正在调用 System.exit(),或者您正在执行 JFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE),无论其他线程正在执行什么,这两者都会导致应用程序立即终止。

【讨论】:

  • 尽管我确信你是对的,但我已经重新检查了我的代码以确保 System.exit() 不会被任何其他 WindowListener 调用,但我无法发现在使用 NetBeans GUI-Builder 创建的 FrameView 上禁用 JFrame.EXIT_ON_CLOSE 的位置。我可能会,当我准备好时......但你有什么快速的想法吗?
【解决方案2】:

这可能不是最好的答案,但我注意到当调用System.exit(0) 时,有时它会切断一切。在调用依赖于上一行结果的方法时,我曾经遇到过问题。一切都应该很好,但是它不能正常工作,因为它在上一行完成之前就执行了下一行。我相信有人可以更多地谈论事件调度线程以及为什么这似乎会发生,尽管关于计算机科学的一切都说它不应该发生。但这是我的想法:向 closeAllConnections 添加一个布尔返回值以在完成时返回 true,然后像这样重写你的窗口侦听器:

    mainFrame().addWindowListener(new java.awt.event.WindowAdapter() {
    @Override
    public void windowClosing(java.awt.event.WindowEvent evt)
    {
        boolean isClosed = false;
        while(!isClosed){
            retrieveItems();
            isClosed = closeAllConnections();
        }    
        System.exit(0);
    }
});

也许这会有所帮助。

【讨论】:

  • 感谢您的帮助...虽然我有点不喜欢循环的东西。但这作为最后的手段可能会非常有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多