How to fork cancellable task into multiple threads

已回答

Upon a run configuration finishing, my plugin starts a task by subclassing Task.Backgroundable and running it using ProgressManager.run. The task may then start many threads as some heavy processing on the AST needs to be done. I would like this to be cancellable if possible and after reading the documentation of ProgressIndicator here: https://github.com/JetBrains/intellij-community/blob/ba6fc7238ab45c184ead61e9ca5cf307d23a9637/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicator.java#L24 thought I could use ProgressManager.runProcess and simply pass the indicator I got from starting the Task.

Following Stacktrace proved this to not be the case:
java.lang.Throwable: Assertion failed: stop() should be called only if start() called before
at com.intellij.openapi.diagnostic.Logger.assertTrue(Logger.java:195)
at com.intellij.openapi.progress.util.AbstractProgressIndicatorBase.stop(AbstractProgressIndicatorBase.java:100)
at com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase.stop(AbstractProgressIndicatorExBase.java:55)
at com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase.delegate(AbstractProgressIndicatorExBase.java:212)
at com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase.doDelegateRunningChange(AbstractProgressIndicatorExBase.java:197)
at com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase.stop(AbstractProgressIndicatorExBase.java:56)
at com.intellij.openapi.wm.impl.status.InfoAndProgressPanel$MyInlineProgressIndicator.stop(InfoAndProgressPanel.java:705)
at com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase.delegate(AbstractProgressIndicatorExBase.java:212)
at com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase.doDelegateRunningChange(AbstractProgressIndicatorExBase.java:197)
at com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase.stop(AbstractProgressIndicatorExBase.java:56)
at com.intellij.openapi.progress.util.ProgressWindow.stop(ProgressWindow.java:298)
at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$2(CoreProgressManager.java:182)
at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:658)
at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:610)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:65)
at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:165)
at com.intellij.openapi.progress.ProgressManager.runProcess(ProgressManager.java:59)
at net.zero9178.cov.data.LLVMCoverageGenerator$processRoot$$inlined$flatMap$lambda$1.get(LLVMCoverageGenerator.kt:217)

Any way I could cancel multiple threads using a simple ProgressIndicator?

0

Sorry for delay. Could you please show your actual code?

0

The code I used to cause the above was: 

ProgressManager.checkCanceled()
try {
llvmFunctions.chunked(
ceil(
data.files.size / Thread.activeCount()
.toDouble()
).toInt()
).map { functions ->
CompletableFuture.supplyAsync {
ProgressManager.getInstance().runProcess<List<CoverageFunctionData>>({
processFunctions(environment, project, demangledNames, file, functions)
}, indicator)
}
}.flatMap { it.join() }
} catch (e: CompletionException) {
val cause = e.cause
if (cause != null) {
throw cause
} else {
throw e
}
}

For surrounding code see https://github.com/zero9178/C-Cpp-Coverage-for-CLion/blob/2fb5ab7c3fa686078568b1cd328c669d384820b9/src/main/kotlin/net/zero9178/cov/data/LLVMCoverageGenerator.kt#L213

The indicator has been created and passed along from here https://github.com/zero9178/C-Cpp-Coverage-for-CLion/blob/2fb5ab7c3fa686078568b1cd328c669d384820b9/src/main/kotlin/net/zero9178/cov/CoverageConfigurationExtension.kt#L182 

 

 

0

>Any way I could cancel multiple threads using a simple ProgressIndicator?

 

yes, you can start progress, and call

ProgressManager.getInstance().executeProcessUnderProgress(progress, ()->{

...

Progressmanager.checkcanceled();

...

}

in multiple threads.
Usually we do one main thread where we do ProgressManager.runProcess(), in which spawn multiple threads,
each calling executeProcessUnderProgress().

0

That worked perfectly! Thank you

0

请先登录再写评论。