boolean (final Runnable runnable) { myThread = Thread.currentThread(); final Semaphore canStart = new Semaphore(); canStart.down(); final Semaphore finished = new Semaphore(); finished.down(); // ProgressManager invokes indicator.checkCanceled only when there's at least one canceled indicator. So we have to create a mock one // on an unrelated thread and cancel it immediately. Future<?> future = ApplicationManager.getApplication().executeOnPooledThread(() -> { final ProgressIndicatorBase mockIndicator = new ProgressIndicatorBase(); ProgressManager.getInstance().runProcess(() -> { mockIndicator.cancel(); canStart.up(); finished.waitFor(); try { ProgressManager.checkCanceled(); TestCase.fail(); } catch (ProcessCanceledException ignored) { } }, mockIndicator); }); ProgressManager.getInstance().runProcess(() -> { canStart.waitFor(); try { runnable.run(); } catch (ProcessCanceledException ignore) { } finally { finished.up(); } }, this); try { future.get(); } catch (InterruptedException | ExecutionException e) { throw new RuntimeException(e); } return isCanceled(); }