javafx中的future.get()阻止了UI更新

javafx中的future.get()阻止了UI更新,javafx,concurrency,task,Javafx,Concurrency,Task,我有一个函数,它应该从任务API的结果返回一个列表 @Override public List performQuery(boolean isPaginationQuery, boolean isSortingQuery { try { TaskImpl taskImpl = new TaskImpl(isPaginationQuery, isSortingQuery); q

我有一个函数,它应该从任务API的结果返回一个列表

    @Override
    public List performQuery(boolean isPaginationQuery, boolean isSortingQuery {

        try {
            TaskImpl taskImpl = new TaskImpl(isPaginationQuery,
                    isSortingQuery);
            queryExecutor.submit(taskImpl).get();
            return taskImpl.get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
执行更新的内部类

private class TaskImpl extends Task<List> {

        private boolean isPaginationQuery, isSortingQuery;

        public TaskImpl(boolean isPaginationQuery, boolean isSortingQuery) {
            this.isPaginationQuery = isPaginationQuery;
            this.isSortingQuery = isSortingQuery;
        }

        @Override
        protected List call() throws Exception {
             Platform.runLater(() -> {
                  loaderContainer.setVisible(true);
                  loaderContainer.toFront();
             });

            HSession hSession = new HSession();
            TaskInfoDao taskInfoDao = new TaskInfoDaoImpl(hSession.getSession(), currentConnection.getConnectionId());
            if (!isPaginationQuery && !isSortingQuery) {
                paginator.setTotal(taskInfoDao.getTaskInfoWithFiltersCount(paginator.getFilterMap(), false));
            }
            Stream<TaskInfo> resultStream = taskInfoDao.getTaskInfoWithFilters(paginator.getFilterMap(), false,
                    paginator.getStartIndex() * paginator.getPageSize(),
                    paginator.getPageSize() * paginator.getPageGap());
            List<TaskInfoTableView> data = createData(resultStream);
            hSession.close();
            return data;
        }

        @Override
        protected void succeeded() {
            super.succeeded();

            try {
                //set the pagination if the task is complete
                //and it is not a pagination query
                if (!isPaginationQuery) {
                    ((TaskInfoViewController) uiController).setPagination(
                            FXCollections.observableArrayList(get()));
                }
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }

        @Override
        protected void cancelled() {
            super.cancelled();
            updateMessage("Cancelled!");
        }

        @Override
        protected void failed() {
            super.failed();
            updateMessage("Failed!");
        }
    }
私有类taskinpl扩展任务{
私有布尔值isPaginationQuery,isSortingQuery;
public TaskImpl(布尔值isPaginationQuery、布尔值isSortingQuery){
this.isPaginationQuery=isPaginationQuery;
this.isSortingQuery=isSortingQuery;
}
@凌驾
受保护的列表调用()引发异常{
Platform.runLater(()->{
loaderContainer.setVisible(true);
loaderContainer.toFront();
});
HSession HSession=新HSession();
TaskInfoDao TaskInfoDao=newtaskinfodaoimpl(hSession.getSession(),currentConnection.getConnectionId());
如果(!isPaginationQuery&&!isSortingQuery){
setTotal(taskInfoDao.getTaskInfoWithFiltersCount(paginator.getFilterMap(),false));
}
Stream resultStream=taskInfoDao.getTaskInfoWithFilters(paginator.getFilterMap(),false,
paginator.getStartIndex()*paginator.getPageSize(),
paginator.getPageSize()*paginator.getPageGap());
列表数据=createData(resultStream);
hSession.close();
返回数据;
}
@凌驾
受保护的无效已成功(){
super.successed();
试一试{
//如果任务已完成,请设置分页
//而且它不是分页查询
如果(!isPaginationQuery){
((TaskInfoViewController)uiController).设置分页(
FXCollections.observearraylist(get());
}
}捕获(中断异常|执行异常e){
e、 printStackTrace();
}
}
@凌驾
受保护的作废已取消(){
super.cancelled();
更新消息(“已取消!”);
}
@凌驾
受保护的void失败(){
super.failed();
updateMessage(“失败!”);
}
}
performQuery函数调用线程并等待其结果。

正在使用Platform.runLater从TaskImpl类内部显示加载程序。
但加载程序在任务完成之前不会出现,即,在call()函数执行完成后,加载程序才会出现。

当我删除taskImpl.get()时,加载程序工作正常。

感谢您的帮助


注意:在任何情况下,我都需要内部类之外的任务API的结果(在TaskImpl之外)

首先,您似乎不太熟悉异步编程。让
performQuery()
返回
列表
表明您希望同步运行此操作-在获得结果之前无法返回结果。这就是为什么要冻结UI

关于异步编程,需要了解的重要一点是,您将在另一个线程中开始执行某些操作(即任务),然后立即返回。当任务返回结果时,可以切换回UI(JavaFX应用程序)线程进行更新。您可以将其视为事件驱动的方法

因此,对于您的情况,您应该直接更新在
taskinpl
类中重写的
succeed()
方法中的列表(在
performQuery()
中返回的列表)

如果您应该更新的列表不在
taskinpl
的范围内,那么您可以使用
java.util.function
包中的函数接口为您进行更新。这意味着您将在正确的范围内创建功能接口对象,并在对象构造期间传入
taskinpl
,并在
successed()
中调用该接口

更新 如果我假设这是调用
performQuery()

公共类MyController{
@FXML
TableView TableView;
公共无效初始化(){
列表结果=queryController.performQuery(true,true);
tableView.getItems().addAll(结果);
}
}
然后,我可能会这样做:

public class MyController {
    @FXML
    TableView<Foo> tableView;

    public void initialize() {
        List result = queryController.performQuery(true, true, list -> tableView.getItems.addAll(list));
    }
}

public class QueryController {
    @Override
    public void performQuery(boolean isPaginationQuery, boolean isSortingQuery, java.util.function.Consumer<List> onQuerySucceeded) {

        try {
            TaskImpl taskImpl = new TaskImpl(isPaginationQuery,
                    isSortingQuery, onQuerySucceeded);

            queryExecutor.submit(taskImpl);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

private class TaskImpl extends Task<List> {

    private final java.util.function.Consumer<List> onQuerySucceeded;

    public TaskImpl(boolean isPaginationQuery, boolean isSortingQuery, java.util.function.Consumer<List> onQuerySucceeded) {
        this.isPaginationQuery = isPaginationQuery;
        this.isSortingQuery = isSortingQuery;

        this.onQuerySucceeded = onQuerySucceeded;
    }

    @Override
    protected void succeeded() {
        super.succeeded();

        // Not sure what the original codes are doing.
        try {
            //set the pagination if the task is complete
            //and it is not a pagination query
            if (!isPaginationQuery) {
                ((TaskInfoViewController) uiController).setPagination(
                        FXCollections.observableArrayList(get()));
            }
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        // This is what is being added in
        onQuerySucceeded.accept(this.getValue());
    }
}
公共类MyController{
@FXML
TableView TableView;
公共无效初始化(){
List result=queryController.performQuery(true,true,List->tableView.getItems.addAll(List));
}
}
公共类查询控制器{
@凌驾
public void性能查询(布尔值isPaginationQuery、布尔值isSortingQuery、java.util.function.Consumer onQuerySucceeded){
试一试{
taskinpl taskinpl=newtaskinpl(isPaginationQuery,
isSortingQuery,onQuerySucceed);
queryExecutor.submit(taskImpl);
}捕获(例外e){
e、 printStackTrace();
}
返回null;
}
}
私有类taskinpl扩展了任务{
private final java.util.function.Consumer onquerysucceed;
public TaskImpl(布尔值isPaginationQuery、布尔值isSortingQuery、java.util.function.Consumer onQuerySucceeded){
this.isPaginationQuery=isPaginationQuery;
this.isSortingQuery=isSortingQuery;
this.onquerysucceed=onquerysucceed;
}
@凌驾
受保护的无效已成功(){
super.successed();
//不知道原始代码在做什么。
试一试{
//如果任务已完成,请设置分页
//而且它不是分页查询
如果(!isPaginationQuery){
((TaskInfoViewController)uiController).设置分页(
FXCollections.observearraylist(get());
}
}捕获(中断异常|执行异常e){
e、 printStackTrace();
}
//这个我
public class MyController {
    @FXML
    TableView<Foo> tableView;

    public void initialize() {
        List result = queryController.performQuery(true, true, list -> tableView.getItems.addAll(list));
    }
}

public class QueryController {
    @Override
    public void performQuery(boolean isPaginationQuery, boolean isSortingQuery, java.util.function.Consumer<List> onQuerySucceeded) {

        try {
            TaskImpl taskImpl = new TaskImpl(isPaginationQuery,
                    isSortingQuery, onQuerySucceeded);

            queryExecutor.submit(taskImpl);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

private class TaskImpl extends Task<List> {

    private final java.util.function.Consumer<List> onQuerySucceeded;

    public TaskImpl(boolean isPaginationQuery, boolean isSortingQuery, java.util.function.Consumer<List> onQuerySucceeded) {
        this.isPaginationQuery = isPaginationQuery;
        this.isSortingQuery = isSortingQuery;

        this.onQuerySucceeded = onQuerySucceeded;
    }

    @Override
    protected void succeeded() {
        super.succeeded();

        // Not sure what the original codes are doing.
        try {
            //set the pagination if the task is complete
            //and it is not a pagination query
            if (!isPaginationQuery) {
                ((TaskInfoViewController) uiController).setPagination(
                        FXCollections.observableArrayList(get()));
            }
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        // This is what is being added in
        onQuerySucceeded.accept(this.getValue());
    }
}