【问题标题】:Javafx - Concurrently reusing javafx Service<>Javafx - 同时重用 javafx 服务<>
【发布时间】:2018-10-22 20:36:44
【问题描述】:

在 JavaFx 上,可重用任务通常在 javafx.concurrent.Service&lt;&gt; 上实现。

问题是:如何管理多次触发Service的多次UI交互?

方法 1 - restart():

我可以使用 service.restart(),但它会取消正在运行的任务并启动一个新任务。这不是想要的结果,因为我不想取消第一个。

方法 2 - start():

为了能够多次使用 start(),我必须这样做:

if(!isRunning()) {
    reset();
    start();
}

但如果isRunning() 为真,则忽略第二次运行。

我想阻止第二次运行,直到第一次运行结束,所以不会丢失 UI 交互。所以我希望阻止或排队任务。

这将如何实现?

【问题讨论】:

    标签: java javafx


    【解决方案1】:

    如果您想阻止用户尝试同时运行两次或多次Service,只需禁用在运行Service 时启动的所有 UI 节点。一种方法是将Nodedisable 属性绑定到Servicerunning 属性。

    如果你想排队执行,那么这取决于Service 的要求。例如,它需要任何输入吗?如果没有,只需有一些 requests 变量并根据需要增加/减少它。

    public class Controller {
    
        private int requests;
        private Service<Object> service = new Service<>() {
    
            @Override
            protected Task<Object> createTask() {
                // create and return Task...
            }
    
            @Override
            protected void succeeded() {
                if (requests > 0) {
                    requests--;
                    restart();
                } 
            }
    
        };
    
        @FXML
        private void startService() {
            if (service.isRunning()) {
                requests++;
            } else {
                service.start();
            }
        }
    
    }
    

    如果Service(或更具体地说,Task)确实需要输入,你仍然会做类似的事情。但是,您可以使用包含每个Task 所需信息的Queue(或其他类似对象),而不是使用int 来跟踪请求的数量。当Service 完成且Queue 不为空时,重新启动Service 并抓取下一个元素。

    【讨论】:

    • 感谢您的回复。我想我可以将队列版本用于某些用例,并在大多数用例上禁用按钮(或启动服务的控件)。
    猜你喜欢
    • 2023-03-21
    • 2012-12-09
    • 2022-12-15
    • 2011-01-04
    • 2015-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多