2

I am new in JavaFX and I have a question about Services. I am trying to read data from a file and if after 5 seconds my task has not done I want to throw TimeOutException:

public Service<Void> readFile() {
    return new Service<Void>() {
        @Override
        protected Task<Void> createTask() {
            return new Task<Void>() {
                @Override
                protected Void call() throws Exception {
                    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                        System.out.println("Trying to read data...");
                        //read data though out a file;
                    });
                    try {
                        future.get(5, TimeUnit.SECONDS);
                    }catch (TimeoutException te) {
                        System.out.println("TIMEOUT!");
                        throw new TimeoutException();
                    }
                    return null;
                }
            };
        }
    };
}

and go to onFailed method to restart the service and do it again and again until it won't be successful. The method which starts my task does it after pressing the button. First starts the animation and if it is finished starts Task:

void readingFile(ActionEvent event) {
    try {
        Parent root = FXMLLoader.load(getClass().getResource("loading.fxml"));
        Scene scene = startBtn.getScene();

        root.translateXProperty().set(scene.getWidth());
        parent.getChildren().add(root);

        Timeline timeline = new Timeline();
        KeyValue keyValue = new KeyValue(root.translateXProperty(), 0 , Interpolator.EASE_IN);
        KeyFrame keyFrame = new KeyFrame(Duration.millis(100), keyValue);
        timeline.getKeyFrames().add(keyFrame);

        timeline.setOnFinished(event1 -> {
            parent.getChildren().remove(container);
            Label label = (Label) root.lookup("#label");
            Service<Void> readTask = readFile();
            label.textProperty().unbind();
            label.textProperty().bind(readTask.messageProperty());
            readTask.start();
            readTask.setOnFailed(fail -> {
                System.out.println("Fail to read file! Retry...");
                readTask.restart();
            });
            readTask.setOnSucceeded(success -> {
                System.out.println("Success");
                new Thread(writeFile()).start();
            });
        });

        timeline.play();

    } catch (IOException e) {
        e.printStackTrace();
    }
}

but when my task is restarted, it skips read data code and falls to try block right away and all the time after 5 seconds throw TimeOutException. Why does it happen and how can I solve it? Thanks in advance.

Scroll
  • 158
  • 2
  • 11
  • 1
    the word "Future" says literally IN THE FUTURE and NOT JET and that is the reason why "it skips read data code and falls to try block right away". Maybe this thread here can help you out of the maze https://stackoverflow.com/questions/34233375/return-completablefuturevoid-or-completablefuture –  Dec 21 '20 at 14:41
  • @Joe Thanks for your answer. May JavaFx has a better way to realize timeout for task without CompletableFuture? – Scroll Dec 21 '20 at 15:27
  • Why would you want to restart reading a file if the complete file has not been read within five seconds? If the file read did not complete within five seconds of the first attempt, what are the chances of it completed in five seconds any attempt after that? – SedJ601 Dec 21 '20 at 16:07
  • After restarting the task I get new data in file that getting though the circuit board connected by usb. And sometimes circuit board does not fulfill the file with new bytes and file is empty that’s why I want to wait for 5 seconds. – Scroll Dec 21 '20 at 18:36
  • Not necessarily related to your problem, but note the thread which actually performs the I/O is never stopped even when a timeout occurs. – Slaw Dec 22 '20 at 00:49

0 Answers0