在后台线程中运行服务 [英] Run Service in background Thread

查看:108
本文介绍了在后台线程中运行服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以在后台线程中运行Service吗?

Can I run Service in background thread?

我想从数据库中加载数据,并且在加载数据期间我希望进度条指示进度.首先,我创建了任务,在后台线程中运行它,然后根据此任务更新进度条.但是,我发现此任务不可重用,因此下次我按下按钮时,它无法正常工作.后来,我发现Service可以多次运行Tasks,因此我将这些任务封装在Service中.

I want to load data from database and during loading data i want progress bar to be indicating progress. First I have created task, run it in background thread and then update progress bar according to this task. However, I found out that this Task is not reusable, so next time i hit the button, it didn't work. Later on, I fount out that Service can run Tasks multiple times, So i have encapsulated those tasks inside of Service.

现在效果很好-每次我按下按钮时,都会重新加载表格-进度条不会移动.

Now it works great - every time i hit button, table is reloaded - except progress bar is not moving.

我如何达到期望的结果?

How can I reach desired result?

推荐答案

好的...这是完整的代码:

Okay... Here is completed code: https://mega.nz/#!yUsjgJyZ!DHfuBqsujAHurS-pQ_W5y8BAflOtvxsm48goRPkDsxA

首先,我想告诉你我的目标是什么

First, i want to tell you what is my goal:

当我运行程序时,我希望进度条处于不确定状态.按下按钮后,我希望进度条反映服务的进度.完成服务后,我希望进度条完成(100%).

When I run program, i want the progress bar to be in indeterminate state. After pressing the button, i want progress bar to reflect progress of Service. After finishing the Service, i want the progress bar to be completed (100%).

这是我所发现的.看起来服务会在后台线程上自动运行其任务.我建立了一个沙盒"程序,在那里我正在使用服务和进度栏.该程序包括进度条,两个文本字段以及它们上方的两个按钮.第一个按钮可以启动service_countTo100,第二个按钮可以运行service_getActualCount.

Here is what i have found. It looks like service automatically runs it's task on background thread. I have built a "sand box" program where i was playing with services and progress bar. The program comprised of progress bar, two text fields with two buttons above them. First button can start service_countTo100 and second button can run service_getActualCount.

现在在fxml文件中,我将进度条设置为不确定的默认状态.按下按钮1之后,开始计数(显示在text_field1中),并且进度条已根据实际进度进行了更改.按下button2之后,count的实际值显示在text_field2中.接下来是一些问题.为了演示这些问题,我将向您展示Service的源代码:

Now in fxml file i set progress bar to indeterminate default state. After pressing the button1, a counting has started (displayed in text_field1) and progress bar has changed according to actual progress. After pressing button2, actual value of count is displayed in text_field2. And here comes some issues. To demonstrate the issues, i will show you source code of Service:

// Create the service
public static Service<Integer> serviceTo100 = new Service<Integer>() {
    @Override
    protected Task<Integer> createTask() {
        Task<Integer> taskTo100 = new Task<Integer>() {
            @Override protected Integer call() throws Exception {

                int iterations;
                updateProgress(-1, 100);
                for (iterations = 0; iterations < 100; iterations++) {
                    if (isCancelled()) {
                        updateMessage("Cancelled");
                        break;
                    }

                    updateMessage("Iteration " + iterations);
                    updateProgress(iterations, 100);

                    // Now block the thread for a short time, but be sure
                    // to check the interrupted exception for cancellation!
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException interrupted) {
                        if (isCancelled()) {
                            updateMessage("Cancelled");
                            break;
                        }
                    }
                }

            //udpateProgress(100, 100);    
            return iterations;
            }
        };
    return taskTo100;
    }
};

如您所见,有一个简单的循环从0到100计数,还有一个updateProgress(iterations, 100);语句更新进度.该服务位于Services类中.在FXMLDocumentController.java中,名为runService(Service service)的方法定义为:

As you can see, there is a simple loop which counts from 0 to 100 and there is also a updateProgress(iterations, 100); statement which updates progress. This service is located in Services class. In FXMLDocumentController.java is method called runService(Service service) defined as this:

public void runService(Service service){

        service.start();
        progressBar.progressProperty().bind(service.progressProperty());

        service.setOnSucceeded((event) -> {
            service.reset();
            progressBar.progressProperty().unbind();
            progressBar.setProgress(1);                                
        });
}

initialize看起来像这样:

@Override
public void initialize(URL url, ResourceBundle rb) {
    btn_start1.setOnAction((event) -> {

        Service service = Services.serviceTo100;
        runService(service);
        txt_field1.textProperty().bind(service.messageProperty());                     
        System.out.printf("something\n");  

    });
    .
    .
    .
    }//end of initialize

现在最有趣的事情(至少对我来说是新手)开始发挥作用.

Now the most interesting thing (at least for me, novice) comes into play.

在服务定义中,您会注意到注释行//updateProgress(100,100).这是我尝试在计数停止时将进度栏设置为完成状态.但是java忽略了这一行.我尝试放入System.out.print("Something");并成功,但是updateProgress(100, 100)无效.计数完成后,进度条被设置为fxml文件中定义的默认状态,该状态是不确定的.

In service definition, you can notice commented line //updateProgress(100,100). That was my try to set progress bar to completed state when counting has stopped. But java ignored that line. I tried to put System.out.print("Something"); and it worked, but updateProgress(100, 100) didn't. When counting has finished, progress bar was set to it's default state defined in fxml file, which was indeterminate.

结论:服务类在其中创建了定义的任务,并且在任务完成之后,该任务不再存在,因此,没有任何要与进度栏绑定的进度.

Conclusion: Service class creates task defined inside of it and after task is completed, the task doesn't exists anymore, thus, there is no progress to be bound with progress bar.

即使不再存在任务,也无法使用setProgress(double double)方法设置有界进度条的进度.您首先需要解除绑定.

Even though task does not exists anymore, you cannot set progress of the bounded progress bar with setProgress(double double) method. You first need to unbound it.

现在我有了所需的东西:

Now I got what i needed:

您运行程序,进度条处于不确定状态,等待命中.您按下按钮,服务开始计数到100,并且进度栏根据服务的progressProperty进行进度.计数完成后,进度栏将再次设置为不确定状态,等待再次开始.

You run the program, progress bar is in indeterminate state, waiting for hit. You hit the button, service starts counting up to 100 and progress bar is progressing according to progressProperty of service. When counting is done, Progress bar is set to indeterminate state again, waiting for another start.

这篇关于在后台线程中运行服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆