Отдельный поток не запускается, блокируя основной интерфейс - PullRequest
0 голосов
/ 10 декабря 2018

У меня есть программа, которая выполняет набор команд 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 голосов
/ 10 декабря 2018

Все обработчики событий JavaFX выполняются в потоке приложений JavaFX, и эти обработчики должны быстро возвращаться, что не происходит с PowerShell.Любая модификация GUI должна происходить в потоке приложения JavaFX.

Похоже, вы просто переместили неправильный код в фоновый поток.

Класс Task может помочь в обработке завершения / исключения кода, выполняемого в фоновом потоке.

@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();
}

Обработчики событий onSucceeded и onFailed выполняются в потоке приложения JavaFX, поэтому вам не нужноиспользуйте Platform.runLater для модификации GUI, выполненного в этих обработчиках.

0 голосов
/ 10 декабря 2018

Поменять, какая часть выполняется в отдельном потоке.Обновления GUI всегда должны выполняться в потоке JavaFX.И наоборот, блокировка вызовов и другая значительная работа должна , а не выполняться в потоке JavaFX.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...