15

我正在开发一个 IntelliJ-idea 插件,并希望在后台任务中运行代码(在后台任务对话框和 UI 之外的另一个线程中可见)。

我找到了以下Helper 类,并通过传递一个 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
4

4 回答 4

12

我找到了一种将进程作为后台任务运行的更好方法,您可以在其中更新进度条百分比和文本

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();
}
于 2013-10-31T10:11:45.330 回答
11

这是一般的解决方案

ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
    public void run() {
        ApplicationManager.getApplication().runReadAction(new Runnable() {
            public void run() {
            // do whatever you need to do
            }
        });
    }
});
于 2013-09-12T16:03:06.790 回答
1

使用 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)
    }
}
于 2021-03-26T09:35:06.450 回答
0

如 API 中所述:

导致 doRun.run() 在 AWT 事件分派线程上异步执行。这将在处理完所有待处理的 AWT 事件后发生。当应用程序线程需要更新 GUI 时,应使用此方法。

SwingUtilities.invokeLater {
    // do something 
}
于 2021-03-02T09:20:13.420 回答