【发布时间】:2025-11-22 21:50:03
【问题描述】:
我正在使用 ScheduledService 来确保服务器连接在应用程序打开时保持活动状态,并且用户不会主动与应用程序交互。
有时应用程序关闭时应用程序线程没有结束,我假设可能是 ScheduledService 导致了我的问题。
由于我的应用程序将包含多个同时打开的阶段,因此我无法在窗口关闭时停止服务。有没有其他方法可以在线程执行过程中查看某个stage当前是否打开,如果没有则取消服务?
//Service set up
service = new KeepSessionAliveService() ;
service.setPeriod(Duration.minutes(REPEAT_PERIOD));
service.setDelay(Duration.minutes(INITIAL_DELAY));
service.start();
private class KeepSessionAliveService extends ScheduledService<Void> {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws ClientProtocolException, IOException {
pingServerToKeepAlive();
return null;
}
};
}
}
如果这不是最好的处理方式,我愿意接受建议。
谢谢。
编辑: 我试图提供服务器访问的默认实现,开发人员只需调用一个包装器方法来提供所需的预期类定义。当调用被调用时,它将在进程运行时提供进度警报,然后在完成时关闭它。最初我尝试了一项服务,但似乎无法使其正常工作,因此建议尝试以下方法:
public <T> void executeServerCall(ServiceRequest serviceRequest, String message, Stage stage, Class<T> valueType, Consumer<T> success, Consumer<Exception> failure) {
Alert progressAlert = displayProgressDialog(message, stage);
Executors.newSingleThreadExecutor().execute(() -> {
try {
T result = executeServerCall(serviceRequest, valueType);
Platform.runLater(() ->
{
forcefullyHideDialog(progressAlert);
success.accept(result);
});
} catch (Exception e) {
Platform.runLater(() ->
{
forcefullyHideDialog(progressAlert);
failure.accept(e);
});
}
});
}
根据您的回复,我确实证明是这段代码让应用程序线程运行,而不是服务。如果我现在可以通过服务完成我所需要的,我会非常乐意改变它。但是我找不到执行以下操作的方法:
public <T> void executeServerCall(ServiceRequest serviceRequest, String message, Stage stage, Class<T> valueType, Consumer<T> success, Consumer<Exception> failure) {
Service<valueType> service = ....
【问题讨论】:
-
默认情况下,
ScheduledService(和Service)将创建一个守护线程来执行创建的任务。 (见Javadocs forService)。因此,除非您为服务指定执行者(在这种情况下显示该代码),否则服务不应该是这里的罪魁祸首。 -
这就是我的假设。但是,当我从 Eclipse 运行时,此服务会在窗口关闭时停止,但是在 EXE 上,FX 线程继续运行。我没有在这个线程上指定一个执行者,但这是我唯一安排的事情。我还使用以下内容: Executors.newSingleThreadExecutor().execute(() -> {});与我的服务器交互。但是,在我关闭应用程序之前,这个线程早就停止了,所以我不认为它可能是那个?我不明白为什么应用程序线程不会停止。
-
Executors.newSingleThreadExecutor()创建一个执行程序,它使用单个线程执行您传递的任何Runnable,但线程将在(每个)Runnable完成后持续存在,除非Runnable由于以下原因而失败一个例外。 (请参阅docs。)从您的代码 sn-p 看来,您正在创建许多这样的执行程序,这是一个非常糟糕的主意,因为最终您的应用程序将遇到线程饥饿。在问题中编辑您正在做什么的详细信息,或创建一个minimal reproducible example。
标签: concurrency javafx-8