A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://plugins.jetbrains.com/docs/intellij/launching-coroutines.html below:

Launching Coroutines | IntelliJ Platform Plugin SDK

Launching Coroutines

This section focuses on explaining coroutines in the specific context of the IntelliJ Platform. If you are not experienced with Kotlin Coroutines, it is highly recommended to get familiar with Learning Resources first.

In the IntelliJ Platform, coroutines can be launched with one of the following approaches:

  1. Service with its own scope.

  2. The currentThreadCoroutineScope function for executing actions.

  3. The runBlockingCancellable function. (not recommended)

Launching Coroutine From Service Scope

The recommended approach is creating a service that receives its scope via the constructor injection and launching a coroutine from the service methods. Note that while creating a service instance does allocate additional resources, using a dedicated service and scope remains a lightweight and fundamentally safe solution for launching coroutines. It should be used whenever possible.

The pattern is as follows:

@Service class MyApplicationService( private val cs: CoroutineScope ) { fun scheduleSomething() { cs.launch { // do something } } }

@Service(Service.Level.PROJECT) class MyProjectService( private val project: Project, private val cs: CoroutineScope ) { fun scheduleSomething() { cs.launch { // do something } } }

The injected scope is created per service, so each instance has its own isolated scope with a common parent, which is an intersection scope. The injected scope is canceled when the container (application/project) is shut down or when the plugin is unloaded.

Using currentThreadCoroutineScope

Action behavior performed in AnAction.actionPerformed() can be executed in a coroutine via currentThreadCoroutineScope:

internal class MyAction : AnAction() { override fun actionPerformed(e: AnActionEvent) { val file = e.getData(LangDataKeys.PSI_FILE) ?: return currentThreadCoroutineScope().launch { // use suspending APIs: val targets = readAction { // do something in read } withContext(Dispatchers.EDT) { // show some UI } } } // ... }

Compared to the service scope approach, using currentThreadCoroutineScope() enables Action System infrastructure to control the launched coroutine and cancel it if needed. In the case of service scopes, the infrastructure code can't control a coroutine launched from an action, as service scopes are "more global" and live longer than the action trigger.

Using runBlockingCancellable

Using runBlockingCancellable is not recommended. Use service scopes whenever possible.

In a standard coroutine-based application, the bridge between the regular blocking code and the suspending code is the runBlocking function.

In the IntelliJ Platform, a similar purpose is achieved by the runBlockingCancellable function. In addition to the same semantics as runBlocking, the action gets canceled when the current progress indicator or the current job is canceled.

If a topic is not covered in the above sections, let us know via the Was this page helpful? feedback form below or other channels.

Be specific about the topics and reasons for adding them and leave your email in case we need more details. Thanks for your feedback!

11 August 2025


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4