public interface NonBlockingReadAction<T>
ProcessCanceledException
and then restarted.
Code blocks running inside should be prepared to get this exception at any moment,
and they should call ProgressManager.checkCanceled()
or ProgressIndicator.checkCanceled()
frequently enough.
They should also be side-effect-free or at least idempotent, to avoid consistency issues when interrupted in the middle and restarted.
The recommended usage is ReadAction.nonBlocking(...).withXxx()....finishOnUiThread(...).submit(...)
.
It's the only way that allows to access the computation result safely. The alternatives
(e.g. executeSynchronously()
, Promise
methods) mean that you might get the computation result
in a background thread after a read action is finished, so a write action can then occur at any time and make the result outdated.Modifier and Type | Method and Description |
---|---|
default NonBlockingReadAction<T> |
cancelWith(ProgressIndicator progressIndicator)
Deprecated.
|
NonBlockingReadAction<T> |
coalesceBy(java.lang.Object... equality)
Merges together similar computations by cancelling the previous ones when a new one is submitted.
|
T |
executeSynchronously()
Run this computation on the current thread in a non-blocking read action, when possible.
|
NonBlockingReadAction<T> |
expireWhen(java.util.function.BooleanSupplier expireCondition)
Returns a copy of this builder that cancels submitted read actions after they become obsolete.
|
NonBlockingReadAction<T> |
expireWith(Disposable parentDisposable) |
NonBlockingReadAction<T> |
finishOnUiThread(ModalityState modality,
java.util.function.Consumer<T> uiThreadAction) |
NonBlockingReadAction<T> |
inSmartMode(Project project) |
CancellablePromise<T> |
submit(java.util.concurrent.Executor backgroundThreadExecutor)
Submit this computation to be performed in a non-blocking read action on background thread.
|
NonBlockingReadAction<T> |
withDocumentsCommitted(Project project) |
NonBlockingReadAction<T> |
wrapProgress(ProgressIndicator progressIndicator) |
NonBlockingReadAction<T> inSmartMode(Project project)
finishOnUiThread(com.intellij.openapi.application.ModalityState, java.util.function.Consumer<T>)
runnable
are completed.DumbService
NonBlockingReadAction<T> withDocumentsCommitted(Project project)
finishOnUiThread(com.intellij.openapi.application.ModalityState, java.util.function.Consumer<T>)
runnable
are completed.PsiDocumentManager
NonBlockingReadAction<T> expireWhen(java.util.function.BooleanSupplier expireCondition)
expireWhen
returns true
).
The conditions are checked when read access is allowed, before the computation on a background thread
and before finishOnUiThread(com.intellij.openapi.application.ModalityState, java.util.function.Consumer<T>)
handler, if any.
Even if the expiration condition becomes true
without a write action during the background computation,
it won't be checked until the computation is complete.
Hence if you want to cancel the computation immediately, you should handle that separately
(e.g. by putting CancellablePromise.cancel()
inside some listener).@Deprecated default NonBlockingReadAction<T> cancelWith(ProgressIndicator progressIndicator)
wrapProgress(com.intellij.openapi.progress.ProgressIndicator)
NonBlockingReadAction<T> wrapProgress(ProgressIndicator progressIndicator)
NonBlockingReadAction
.
This means that submitted read actions are cancelled once the outer indicator is cancelled,
and the visual changes (e.g. ProgressIndicator.setText(java.lang.String)
) are propagated from the inner to the outer indicator.NonBlockingReadAction<T> expireWith(Disposable parentDisposable)
CancellablePromise
will be canceled immediately, its completion handlers will be called.
Currently running background computations will throw a ProcessCanceledException
on the next checkCanceled
call,
and if computations or finishOnUiThread(com.intellij.openapi.application.ModalityState, java.util.function.Consumer<T>)
handlers are scheduled, they won't be executed.NonBlockingReadAction<T> finishOnUiThread(ModalityState modality, java.util.function.Consumer<T> uiThreadAction)
NonBlockingReadAction<T> coalesceBy(java.lang.Object... equality)
equality
- objects that together identify the computation: if they're all equal in two submissions,
then the computations are merged. Callers should take care to pass something unique there
(e.g. some Key
or this
getClass()
),
so that computations from different places won't interfere.CancellablePromise<T> submit(java.util.concurrent.Executor backgroundThreadExecutor)
finishOnUiThread(com.intellij.openapi.application.ModalityState, java.util.function.Consumer<T>)
has been called.backgroundThreadExecutor
- an executor to actually run the computation. Common examples are
com.intellij.util.concurrency.NonUrgentExecutor#getInstance()
or
AppExecutorUtil.getAppExecutorService()
or
BoundedTaskExecutor
on top of that.T executeSynchronously() throws ProcessCanceledException
submit(java.util.concurrent.Executor)
API where possible,
preferably coupled with finishOnUiThread(com.intellij.openapi.application.ModalityState, java.util.function.Consumer<T>)
to ensure result validity.
If the current thread already has read access, the computation is executed as is, without any write-action-cancellability.
It's the responsibility of the caller to take care about it.
finishOnUiThread(com.intellij.openapi.application.ModalityState, java.util.function.Consumer<T>)
and coalesceBy(java.lang.Object...)
are not supported with synchronous non-blocking read actions.ProcessCanceledException
- if the computation got expired due to expireWhen(java.util.function.BooleanSupplier)
or expireWith(com.intellij.openapi.Disposable)
or wrapProgress(com.intellij.openapi.progress.ProgressIndicator)
.java.lang.IllegalStateException
- if current thread already has read access and the constraints (e.g. inSmartMode(com.intellij.openapi.project.Project)
are not satisfied)java.lang.RuntimeException
- when the computation throws an exception. If it's a checked one, it's wrapped into a RuntimeException
.