ProgressManager.getInstance().executeNonCancelableSection() runs in GUI thread

Answered

I have a button in a tool window. When the button is clicked the following code is run:

 

ProgressManager.getInstance().executeNonCancelableSection(() -> {
List<PipelineJobStatus> statuses = getStatuses();
project.getMessageBus().syncPublisher(ReloadListener.RELOAD).reload(statuses);
});

The loading takes a while and I got UI freeze messages. I debugged the code and saw that the internal code is executed in the main AWT thread.

According to https://www.jetbrains.org/intellij/sdk/docs/basics/architectural_overview/general_threading_rules.html the call to executeNonCancelable() should execute it in a background thread.

What is the reason for that and how I can I solve the problem?

Thanks!

0
4 comments

I managed to get it done this way:

 

refreshToolWindowButton.addActionListener(e -> {
Task.Backgroundable task = new Task.Backgroundable(project, "Loading Gitlab Pipelines") {
@Override
public void run(@NotNull ProgressIndicator indicator) {
loadPipelines();
}
};
ProgressManager.getInstance().runProcessWithProgressAsynchronously(task, new BackgroundableProcessIndicator(task));
});

 

Although that's not exactly what I wanted at least the code is running asynchronously.

0

>the call to executeNonCancelable() should execute it in a background thread.
Which part of this page are you reffering to?
This method calls callback synchronously while suppressing PCE from `checkCancelled` being thrown inside (see its javadoc).

If you need to run task on a pooled thread, you can use `com.intellij.openapi.application.ApplicationManager.getApplication().executeOnPooledThread()`, `com.intellij.util.Alarm`, `com.intellij.util.concurrency.AppExecutorUtil.createBoundedApplicationPoolExecutor`.

UPD: Yes, Task.Modal/Task.Backgroundable is an another option.

0

Thanks, Aleksey,

the current documentation at https://www.jetbrains.org/intellij/sdk/docs/basics/architectural_overview/general_threading_rules.html says

"Background progresses are managed by ProgressManager class, which has plenty of methods to execute the given code with a modal (dialog), non-modal (visible in the status bar) or invisible progress. In all cases, the code is executed on a background thread which is associated with a ProgressIndicator object,"

So I expected the code to be run in a background thread. Am I misunderstanding it or is that sentence actually too broad?

 

0

Thanks for clarification.
Probably, this piece was referring to `runProcessWithProgressAsynchronously`/`runProcessWithProgressSynchronously` (that delegate to Task you've used).

You can also use `new Task.Backgroundable() { ... }.queue()`.

0

Please sign in to leave a comment.