Ожидание задачи JavaFX - PullRequest
0 голосов
/ 09 мая 2020

Я не уверен, возможно ли то, что я пытаюсь сделать. Но если у кого-то есть идеи, это было бы здорово.

Вот сценарий. Я пытаюсь выполнить задачу A с индикатором выполнения, показывающим прогресс, и после завершения задачи A я пытаюсь выполнить задачу B. Вот пример в коде:

private void func() {

    // Task A
    class CustomTask extends Task<Integer> {
        @Override
        protected Integer call() throws Exception {
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                updateProgress(i, 4);
            }
            return null;
        }
    }

    // Executing Task A
    // CustomProgressBar is a class I made that just binds the progress Property,
    // And the progress bar appears to work.
    CustomTask customTask = new CustomTask();
    CustomProgressBar customProgressBar = new CustomProgressBar(customTask);
    Thread thread = new Thread(customTask);
    thread.start();

    // Task B, For example, just a simple print statement
    System.out.println("After task A is finished");

}

В этом примере я необходимо, чтобы задача B выполнялась после завершения задачи A. Однако я не могу использовать thread.join(), потому что это заблокирует поток JavaFX, и индикатор выполнения не будет обновляться.

Есть ли способ выполнить sh это, не помещая задачу B в customTask.setOnSucceeded()?

Ответы [ 2 ]

2 голосов
/ 09 мая 2020

onSucceeded кажется одним из наиболее удобных вариантов для этого. Однако есть альтернативы:

Запустить обе задачи самостоятельно из фонового потока

Следующий код всегда будет запускать вторую задачу, если вы не добавите проверку. В основном вы вызываете Task.run в фоновом потоке, самостоятельно выполняя logi c обоих потоков из этого потока. Вам может потребоваться использовать Platform.runLater, если вы хотите изменить некоторые привязки при изменении задач.

Thread t = new Thread(() -> {
    firstTask.run();
    secondTask.run();
});
t.start();

Используйте ExecutorService

Вы можете использовать однопоточный ExecutorService, чтобы в основном делать указанное выше.

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(firstTask);
executor.submit(secondTask);

...
// Make sure the ececutor is eventually shut down
executor.shutdown();
1 голос
/ 09 мая 2020

Вы можете добавить ChangeListener к свойству state taskA, и если состояние изменится на SUCCEEDED, вы можете начать taskB.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...