У меня есть внешний Processor.process(...)
тяжелый метод, который может работать в течение длительного времени (десятки минут) в обычном случае.JavaFX завершение фоновой задачи
Я хочу показать экран загрузки с помощью кнопки «Отмена» и запустить этот Processor
в фоновом режиме. Я хочу прекратить выполнение фоновой задачи, когда нажата кнопка «Отменить».
Проблема в том, что у меня есть один звонок до Processor.process(...)
. Если бы у меня была какая-то задача в цикле, я бы делал проверки вроде if(isCancelled()){ break; }
или подобные на каждой итерации.
Есть ли способ до Окончить | убить что тяжелая задача фона? Давайте предположим, что Processor.process(...)
очень долго «атомная» операция (я просто не хочу, чтобы изменить всю логику глубоко позади него, чтобы выполнить одну задачу)
Вот как я начала загрузки экрана и фоновое задание:
private void handleProcess(ActionEvent event) {
SomeService service = new SomeService();
// ... configuring service
Stage loadingStage = new Stage();
// ... configuring 'loading' stage
service.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent t) {
@SuppressWarnings("unchecked")
Entity entity = (Entity) t.getSource().getValue();
// ... do some stuff
loadingStage.close();
}
});
service.start(); // launch background process
loadingStage.show(); // show 'loading' screen
}
ОБНОВЛЕНО Вот Сервис для фоновой работы:
private static class SomeService extends Service<Entity> {
private Thread threadToStopOnCancel; // added
// fields, getters, setters omitted
protected Task<Entity> createTask() {
// _params initialization omitted
return new Task<Entity>() {
protected Entity call() throws IOException {
threadToStopOnCancel = Thread.currentThread(); // added
return Processor.process(_params);
}
};
}
@SuppressWarnings("deprecation")
@Override
protected void cancelled() {
if (threadToStopOnCancel != null) { threadToStopOnCancel.stop(); } // added
super.cancelled();
}
на данный момент, я называю service.cancel();
с загрузочного экрана. Но он просто устанавливает состояние service's
в положение «ОТМЕНА», и задача все еще работает в фоновом режиме.
Отлично, спасибо. Я обновил последний фрагмент кода, он работает сейчас, как ожидалось, но для меня это немного странно. Можете ли вы предложить что-нибудь лучше? –
Я не понял, что метод 'cancel()' устарел. В любом случае вы все равно можете получить тот же эффект, создав новый 'EventHandler' для метода' setOnCancelled() ', как вы это делали с методом' setOnSucceeded() ' – pulse0ne
' cancel() 'не устарело. Я добавил подавление для метода 'stop()' потока. –