1

我正在使用 JavaFx API 中的Task 类来执行网络操作。该类提供了一个似乎非常适合这种情况的进度系统,例如,允许报告上传到调用者线程的文件数量。为此,每次成功上传文件时,我都会调用updateMessage(x + "files Uploads") 。

问题是我收到的唯一一条消息是最后一条消息,此时每个文件都已上传。我想Javadoc以某种方式解释了这种现象:

对 updateMessage 的调用被合并并稍后在 FX 应用程序线程上运行,因此对 updateMessage 的调用,即使是从 FX 应用程序线程,也不一定会立即更新此属性,并且可能会合并中间消息值以保存事件通知。

我怎样才能让它正确地报告每条消息,或者至少是一些消息?我试图在它周围添加一些 Thread.sleep(20) 但它不起作用。任何想法?

4

2 回答 2

3

很可能您正在事件线程上运行任务,因此它会阻止更新。Task 实现了 Runnable,这有点误导,但通过查看 javadoc,您可以发现运行 Task 的正确方法是将其分配给新线程:new Thread(task).start();

请参见下一个示例:

public class TaskTask extends Application {
    public static void main(String[] args) { launch(args); }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle(VersionInfo.getRuntimeVersion());
        Button btn = new Button();

        final Task<Integer> task = new Task<Integer>() {
            @Override
            protected Integer call() throws Exception {
                int iterations;
                for (iterations = 0; iterations < 100; iterations++) {
                    if (isCancelled()) {
                        break;
                    }
                    Thread.sleep(100); // imitate activity
                    updateMessage("Iteration " + iterations);
                }
                return iterations;
            }
        };

        // here we monitor task updates
        btn.textProperty().bind(task.messageProperty());

        btn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                //here it goes
                new Thread(task).start();
            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(btn);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();

    }
}
于 2012-06-27T12:45:58.020 回答
1

好吧,我的错。我错误地收听了消息更新:我在 Task 上使用了 EventHandler,而不是在 messageProperty 上使用了 ChangeListener。javadoc 仅指示如何发送更新,而不是接收更新,所以我尝试了,但 Sergey 的回答是正确的方法。

于 2012-06-27T13:53:39.523 回答