为 Eclipse RCP 应用程序添加 Shutdown Hook 的正确方法是什么?

发布于 2024-07-13 23:31:36 字数 186 浏览 5 评论 0原文

我有一个 RCP 应用程序,它使用与内存数据库的连接。 有一种情况是,当关闭窗口时,应用程序被终止,而没有给它机会关闭与数据库的连接。

我做了一些研究,似乎添加 Shutdown 挂钩是检测此事件并在 Java 应用程序中进行清理的最佳方法。 但是,如果您有 RCP 应用程序(可能打开了多个编辑器),处理此问题的正确方法是什么?

I have an RCP application that uses a connection to a in-memory database. There is one circumstance that, when shutting down windows, the application is killed without giving it a chance to close the connection to the database.

I researched a little and it seems that adding a Shutdown hook is the best way to detect this event and do cleanup in a Java application. However, what is the correct way to do process this if you have an RCP application, possibly with multiple editors open?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

面如桃花 2024-07-20 23:31:36

注意:此博客条目建议对关闭挂钩执行以下实现:

关闭代码必须在 UI 线程中运行,如果工作台通过其他方式关闭,则不应运行关闭代码。 所有脏编辑器都会自动保存。 这可以避免在计算机关闭时提示可能在家睡觉的用户。 最后工作台关闭。

(所以不完全是您的场景,但实现仍然很有趣,因为它展示了如何在 UI 线程中运行它)

private class ShutdownHook extends Thread {
  @Override
  public void run() {
    try {
      final IWorkbench workbench = PlatformUI.getWorkbench();
      final Display display = PlatformUI.getWorkbench()
                                        .getDisplay();
      if (workbench != null && !workbench.isClosing()) {
        display.syncExec(new Runnable() {
          public void run() {
            IWorkbenchWindow [] workbenchWindows = 
                            workbench.getWorkbenchWindows();
            for(int i = 0;i < workbenchWindows.length;i++) {
              IWorkbenchWindow workbenchWindow =
                                        workbenchWindows[i];
              if (workbenchWindow == null) {
                // SIGTERM shutdown code must access
                // workbench using UI thread!!
              } else {
                IWorkbenchPage[] pages = workbenchWindow
                                           .getPages();
                for (int j = 0; j < pages.length; j++) {
                  IEditorPart[] dirtyEditors = pages[j]
                                           .getDirtyEditors();
                  for (int k = 0; k < dirtyEditors.length; k++) {
                    dirtyEditors[k]
                             .doSave(new NullProgressMonitor());
                  }
                }
              }
            }
          }
        });
        display.syncExec(new Runnable() {
          public void run() {
            workbench.close();
          }
        });
      }
    } catch (IllegalStateException e) {
      // ignore
    }
  }
}

正如您所说,它是在 IApplication 中设置的:

public class IPEApplication implements IApplication {
  public Object start(IApplicationContext context) throws Exception {
    final Display display = PlatformUI.createDisplay();
    Runtime.getRuntime().addShutdownHook(new ShutdownHook());  }
    // start workbench...
  }
}

Note: this blog entry suggests the following implementation for the shutdown hook:

The shutdown code must be run in the UI thread and should not be run if the workbench is being closed by other means. All dirty editors are automatically saved. This avoids prompting the user who is probably at home sleeping when their computer is shutdown. Finally the workbench is closed.

(so not exactly your scenario, but the implementation is still interesting in that it shows how to run it within the UI thread)

private class ShutdownHook extends Thread {
  @Override
  public void run() {
    try {
      final IWorkbench workbench = PlatformUI.getWorkbench();
      final Display display = PlatformUI.getWorkbench()
                                        .getDisplay();
      if (workbench != null && !workbench.isClosing()) {
        display.syncExec(new Runnable() {
          public void run() {
            IWorkbenchWindow [] workbenchWindows = 
                            workbench.getWorkbenchWindows();
            for(int i = 0;i < workbenchWindows.length;i++) {
              IWorkbenchWindow workbenchWindow =
                                        workbenchWindows[i];
              if (workbenchWindow == null) {
                // SIGTERM shutdown code must access
                // workbench using UI thread!!
              } else {
                IWorkbenchPage[] pages = workbenchWindow
                                           .getPages();
                for (int j = 0; j < pages.length; j++) {
                  IEditorPart[] dirtyEditors = pages[j]
                                           .getDirtyEditors();
                  for (int k = 0; k < dirtyEditors.length; k++) {
                    dirtyEditors[k]
                             .doSave(new NullProgressMonitor());
                  }
                }
              }
            }
          }
        });
        display.syncExec(new Runnable() {
          public void run() {
            workbench.close();
          }
        });
      }
    } catch (IllegalStateException e) {
      // ignore
    }
  }
}

It is set, as you said, in the IApplication:

public class IPEApplication implements IApplication {
  public Object start(IApplicationContext context) throws Exception {
    final Display display = PlatformUI.createDisplay();
    Runtime.getRuntime().addShutdownHook(new ShutdownHook());  }
    // start workbench...
  }
}
哀由 2024-07-20 23:31:36

您应该重写扩展 WorkbenachAdvisor 的类上的 preShutdown 方法。 返回 false 以停止关闭过程,或返回 true 以继续。

You should override the preShutdown method on your class that extends WorkbenachAdvisor. Return false to halt the shutdown process or true to continue.

情释 2024-07-20 23:31:36

在实际启动 RCP 应用程序之前,我尝试了从 IApplication 实现者 start() 方法执行以下代码:

Runtime.getRuntime().addShutdownHook(new Thread() {
    public void run() {
        if (PlatformUI.isWorkbenchRunning()) {
            PlatformUI.getWorkbench().close();
        }
        logger.info("Shutdown request received");
        cleanup();
    }
});

其中 cleanup() 关闭与数据库的连接。 如果有任何文档打开,关闭应要求用户保存。

I tried the following code, that I execute from my IApplication implementor start() method, before the RCP application is actually launched:

Runtime.getRuntime().addShutdownHook(new Thread() {
    public void run() {
        if (PlatformUI.isWorkbenchRunning()) {
            PlatformUI.getWorkbench().close();
        }
        logger.info("Shutdown request received");
        cleanup();
    }
});

Where cleanup() closes the connection to the database. Close should ask the users to save if there is any documents open.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文