Асинхронные задачи
Бин UiAsyncTasks позволяет выполнить операцию в отдельном потоке с использованием контекста безопасности текущего пользователя, а затем обновить экран с результатом этой операции.
Бин UiAsyncTasks использует под капотом CompletableFuture.
Если необходимо показать прогресс операции и дать пользователям возможность прервать её, используйте более мощный механизм фоновых задач.
Асинхронные задачи с результатом
Чтобы выполнить задачу, возвращающую результат, используйте билдер supplierConfigurer() и терминальный метод supplyAsync():
@Autowired
private UiAsyncTasks uiAsyncTasks;
private void loadCustomersAsync() {
    uiAsyncTasks.supplierConfigurer(this::loadCustomers) (1)
            .withResultHandler(customers -> {
                customersDc.setItems(customers); (2)
                notifications.create("Customers loaded").show();
            })
            .supplyAsync();
}
private List<Customer> loadCustomers() {
    return customerService.loadCustomers();
}| 1 | Supplier, переданный в метод supplierConfigurer(), будет выполнен с использованием контекста безопасности текущего пользователя. | 
| 2 | Код, выполняемый внутри потребителя withResultHandler(), может безопасно обновлять компоненты экрана. | 
Асинхронные задачи без результата
Чтобы выполнить задачу, не возвращающую результат, используйте билдер runnableConfigurer() и терминальный метод runAsync():
private void synchronizeCustomersAsync() {
    uiAsyncTasks.runnableConfigurer(this::synchronizeCustomers)
            .withResultHandler(() -> {
                resultField.setValue("Synchronization completed");
            })
            .runAsync();
}
private void synchronizeCustomers() {
    customerService.synchronizeCustomers();
}Обработка исключений
По умолчанию, если выполнение задачи завершится с исключением, оно будет записано в журнал приложения. Вы можете настроить это поведение, предоставив обработчик исключений:
private void loadCustomersAndHandleException() {
    uiAsyncTasks.supplierConfigurer(this::loadCustomers)
            .withResultHandler(customers -> {
                //...
            })
            .withExceptionHandler(ex -> {
                errorField.setValue(ex.getMessage());
            })
            .supplyAsync();
}Обработка таймаутов
Используйте метод withTimeout(), чтобы задать значение таймаута выполнения. Если время ожидания превышено, будет выброшено исключение TimeoutException. Исключение TimeoutException можно обработать в методе withExceptionHandler().
private void loadCustomersWithTimeout() {
    uiAsyncTasks.supplierConfigurer(this::loadCustomers)
            .withResultHandler(customers -> {
                //...
            })
            .withTimeout(20, TimeUnit.SECONDS)
            .withExceptionHandler(ex -> {
                String errorText;
                if (ex instanceof TimeoutException) {
                    errorText = "Timeout exceeded";
                } else {
                    errorText = ex.getMessage();
                }
                errorField.setValue(errorText);
            })
            .supplyAsync();
}Если явные значения таймаута не указаны, будет использоваться значение по умолчанию — 5 минут. Чтобы изменить это значение по умолчанию, используйте свойство приложения jmix.ui.async-task.default-timeout-sec.
Конфигурация ExecutorService
Бин UiAsyncTasks использует собственный ExecutorService для выполнения задач в отдельных потоках. Чтобы изменить размер пула по умолчанию для ExecutorService, используйте свойство приложения jmix.ui.async-task.executor-service.maximum-pool-size.