独立线程将无法运行,从而阻止主界面

时间:2018-12-09 23:49:27

标签: java javafx

我有一个程序,可以执行一组PowerShell命令。现在的问题是,当用户单击某个选项并且执行命令的过程开始时,我需要更新标签的状态并显示图标。如果我只是在try-catch语句之前键入命令,它们将在整个try-catch语句结束之后在结尾处执行。因此,我尝试在下面提供的代码中的单独线程上运行它们,但是在这种情况下,甚至没有执行它们,只是try-catch块被执行了。通过鼠标单击触发NORMAL_MODE()方法。

@FXML
    private void NORMAL_MODE(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                LABEL.setText("123");
                ICON.setVisible(true);
            }
        }).start();
        try (PowerShell powerShell = PowerShell.openSession()) {
            PowerShellResponse response = powerShell.executeCommand("Set-Location “C:\\Windows\\Temp”");
            response = powerShell.executeCommand("Remove-Item * -whatif -recurse -force");
            System.out.println(response.getCommandOutput());
            response = powerShell.executeCommand("Set-Location “C:\\Windows\\Prefetch”");
            response = powerShell.executeCommand("Remove-Item * -whatif -recurse -force");
            System.out.println(response.getCommandOutput());
            response = powerShell.executeCommand("Set-Location “C:\\Documents and Settings”");
            response = powerShell.executeCommand("Remove-Item * -whatif -recurse -force");
            System.out.println(response.getCommandOutput());
            response = powerShell.executeCommand("Set-Location $env:TEMP");
            System.out.println(response.getCommandOutput());
            response = powerShell.executeCommand("Remove-Item -whatif -Recurse -Force");
            System.out.println(response.getCommandOutput());
        } catch(PowerShellNotAvailableException ex) {
        }
    }

2 个答案:

答案 0 :(得分:1)

所有JavaFX事件处理程序都在JavaFX应用程序线程上运行,并且这些处理程序需要快速返回,而PowerShell不会发生这种情况。对GUI的任何修改都需要在JavaFX应用程序线程上进行。

似乎您只是将错误的代码移到了后台线程。

Task class可以帮助处理在后台线程上执行的代码的完成/异常。

@FXML
private void NORMAL_MODE(){
    LABEL.setText("123");
    ICON.setVisible(true);

    Task<Void> task = new Task<Void>() {
        @Override
        protected Void call() throws Exception {
             try (PowerShell powerShell = PowerShell.openSession()) {
                PowerShellResponse response = powerShell.executeCommand("Set-Location “C:\\Windows\\Temp”");
                response = powerShell.executeCommand("Remove-Item * -whatif -recurse -force");
                System.out.println(response.getCommandOutput());
                response = powerShell.executeCommand("Set-Location “C:\\Windows\\Prefetch”");
                response = powerShell.executeCommand("Remove-Item * -whatif -recurse -force");
                System.out.println(response.getCommandOutput());
                response = powerShell.executeCommand("Set-Location “C:\\Documents and Settings”");
                response = powerShell.executeCommand("Remove-Item * -whatif -recurse -force");
                System.out.println(response.getCommandOutput());
                response = powerShell.executeCommand("Set-Location $env:TEMP");
                System.out.println(response.getCommandOutput());
                response = powerShell.executeCommand("Remove-Item -whatif -Recurse -Force");
                System.out.println(response.getCommandOutput());
            }
            return null;
        }

    };
    task.setOnSucceeded(event -> {
        // todo: update gui to indicate success
    });
    task.setOnFailed(event -> {
        // todo: update gui to indicate an exception happened
    });

    new Thread(task).start();
}

onSucceededonFailed事件处理程序在JavaFX应用程序线程上执行,因此您不需要使用Platform.runLater来修改在这些处理程序中进行的GUI。

答案 1 :(得分:0)

交换哪个部分在单独的线程中执行。 GUI更新应始终在JavaFX线程上进行。相反,阻塞调用和其他重要工作不应在JavaFX线程上完成。