我正在开发一个IntelliJ-idea插件,并希望在后台任务中运行代码(在后台任务对话框中和在UI之外的另一个线程中可见)。
我找到了以下Helper class并尝试通过传递Runnable对象并实现其run方法,但它仍然阻止了UI,当我尝试自行执行线程时,我收到了以下错误
Read access is allowed from event dispatch thread or inside read-action only (see com.intellij.openapi.application.Application.runReadAction())
Details: Current thread: Thread[Thread-69 [WriteAccessToken],6,Idea Thread Group] 532224832
Our dispatch thread:Thread[AWT-EventQueue-1 12.1.4#IU-129.713, eap:false,6,Idea Thread Group] 324031064
SystemEventQueueThread: Thread[AWT-EventQueue-1 12.1.4#IU-129.713, eap:false,6,Idea Thread Group] 324031064
答案 0 :(得分:6)
这是一般解决方案
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
public void run() {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
// do whatever you need to do
}
});
}
});
答案 1 :(得分:6)
我找到了一种更好的方法,可以将流程作为后台任务运行,并更新进度条百分比和文本
ProgressManager.getInstance().run(new Task.Backgroundable(project, "Title"){
public void run(@NotNull ProgressIndicator progressIndicator) {
// start your process
// Set the progress bar percentage and text
progressIndicator.setFraction(0.10);
progressIndicator.setText("90% to finish");
// 50% done
progressIndicator.setFraction(0.50);
progressIndicator.setText("50% to finish");
// Finished
progressIndicator.setFraction(1.0);
progressIndicator.setText("finished");
}});
如果您需要从其他线程中读取一些数据,您应该使用
AccessToken token = null;
try {
token = ApplicationManager.getApplication().acquireReadActionLock();
//do what you need
} finally {
token.finish();
}
答案 2 :(得分:0)
如 API 中所述:
<块引用>导致 doRun.run() 在 AWT 事件上异步执行 调度线程。这将在所有待处理的 AWT 事件发生后发生 被处理。当应用程序线程 需要更新 GUI。
SwingUtilities.invokeLater {
// do something
}
答案 3 :(得分:0)
使用 kotlin 运行后台任务的新方法
import com.intellij.openapi.progress.runBackgroundableTask
runBackgroundableTask("My Backgrund Task", project) {
for (i in 0..10 step 1) {
it.checkCanceled()
it.fraction = i / 10.0
sleep(i * 100L)
}
}