首页 > 解决方案 > 在任务中更新消息会挂起应用程序

问题描述

我正在使用背景Thread来运行我的加载代码并希望将其绑定MessagePropertyTask标签。

但是,调用updateMessage()任务时挂起;消息永远不会更新,下一行代码也不会执行。

这是使用 JDK 1.10.1。这是一个 MCVE:

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        VBox root = new VBox(10);
        Label label = new Label("Message");
        root.getChildren().add(label);

        primaryStage.setScene(new Scene(root));

        Task loadingTask = new LoadingTask();
        Thread loadingThread = new Thread(loadingTask);
        loadingThread.setDaemon(true);

        label.textProperty().bind(loadingTask.messageProperty());
        loadingThread.start();

        primaryStage.setWidth(200);
        primaryStage.setHeight(200);
        primaryStage.show();
    }
}

class LoadingTask<Void> extends Task {
    @Override
    protected Object call() throws Exception {
        System.out.println("Loading task ...");
        updateMessage("Loading task ...");
        System.out.println("Message: " + getMessage());

        return null;
    }
}

输出:

Loading task ...

第二个System.out.println()永远不会被执行。

编辑:

我向我的 MCVE 添加了一个简单的 GUI,标签绑定到MessageProperty. 标签确实更新为显示“正在加载任务...”,但控制台输出保持不变;调用方法后的代码updateMessage()不会执行。

第二次编辑:

我运行了我的步进调试器,并IllegalStateException从类中抛出了一个Task:“任务只能从 FX 应用程序线程中使用”

我不确定这意味着什么,因为重点是在不同的线程上运行这个任务......

标签: javajavafxjava.util.concurrent

解决方案


您唯一的问题是,您不能getMessage()从 FX UI-Thread 以外的其他线程访问。尝试Platform.runLater(() -> System.out.println("Message: " + getMessage()));


推荐阅读