【问题标题】:Create a background task in IntelliJ plugin在 IntelliJ 插件中创建后台任务
【发布时间】:2013-09-14 13:00:42
【问题描述】:

我正在开发一个 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

【问题讨论】:

    标签: java intellij-idea intellij-plugin


    【解决方案1】:

    这是一般的解决方案

    ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
        public void run() {
            ApplicationManager.getApplication().runReadAction(new Runnable() {
                public void run() {
                // do whatever you need to do
                }
            });
        }
    });
    

    【讨论】:

    • 这段代码应该保存在哪里,以便在构建完成后立即执行?
    【解决方案2】:

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

    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();
    }
    

    【讨论】:

    • 能否请您添加更多关于如何关闭进度指示器以及如何使用令牌更改 UI 的代码
    【解决方案3】:

    如 API 中所述:

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

    SwingUtilities.invokeLater {
        // do something 
    }
    

    【讨论】:

    • 虽然此代码可能会解决问题,including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请编辑您的答案以添加解释并说明适用的限制和假设。
    【解决方案4】:

    使用 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)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-10
      • 1970-01-01
      • 1970-01-01
      • 2016-11-22
      • 1970-01-01
      • 1970-01-01
      • 2014-03-21
      相关资源
      最近更新 更多