Eclipse RCP多线程

4

我有一个Eclipse RCP应用程序。当执行某个命令时,需要启动一个线程。线程执行完毕后,必须更新GUI。但是我认为此线程或其他非SWT线程无法更新GUI,尽管这似乎合理。当我尝试这样做时,我遇到了Exception in thread "Thread-5" org.eclipse.swt.SWTException: Invalid thread access错误。我如何实现这个目标?

6个回答

6

使用SWT时,需要确保所有更新GUI的操作必须在主线程中完成,在Eclipse中,它被称为UI线程(它是同一个线程)。如果你尝试在另一个线程上访问SWT对象,就会出现此错误。考虑使用Display.syncExec()Display.asyncExec()将与SWT相关的处理移动到主线程中。使用syncExec()时要注意不要引起死锁。


是的!“您之所以会收到此错误,是因为您正在尝试在另一个线程上访问SWT对象。”这就是我在我的帖子中说的内容。您能详细解释一下什么是 Display.syncExec() 或 Display.asyncExec() 以及如何在 Eclipse RCP 中使用它们吗? - itun
你可以查看它们的Javadoc或者在Google上搜索,有很多例子。它们基本上在UI线程上运行代码,这样你就可以访问SWT对象了。 - Francis Upton IV

2
通常在 RCP 应用程序中我不会使用 java.lang.Thread,因为 Eclipse 通过 Jobs API(https://eclipse.org/articles/Article-Concurrency/jobs-api.html)提供了不同的抽象层次和对长时间运行操作的控制。以下是您问题的解决方案:
    Runnable uiUpdater = new Runnable() {
        public void run() {
            // update SWT UI safely here
            // ...
        }
    };
    Job longRunningOperation = new Job("My command") {
        protected IStatus run(IProgressMonitor monitor) {
            // some time consuming code here        
            // ...      
            Display.getDefault().asyncExec(uiUpdater);
            return Status.OK_STATUS;
        }
    };
    longRunningOperation.schedule();

1
你遇到了这个异常,是因为你试图从非 UI 线程访问 UI 线程。 使用 Display.syncExec()Display.asyncExec() 可以解决你的问题。

1

0
你面临 SWT 世界中最常见的异常!Invalid Thread Access 意味着只有一件事:你想要修改或者简单地访问 GUI 元素,但是你正在一个不是 GUI 线程的线程中执行。

当你的代码在点击按钮或类似操作时,这种情况永远不会发生,但是当你使用后台进程或异步通知时,它会一直发生。

有一个解决方案:在特定的块中执行你的代码:

Display.getDefautl().syncExec(new Runnable() {
   public void run() {
      // code related to GUI element(s)
   }
}

或者

Display.getDefautl().asyncExec(new Runnable() {
   public void run() {
      // code related to GUI element(s)
   }
}

在第一种情况下,执行是同步的。调用线程等待run方法被执行。在第二种情况下,调用线程不会等待。
要了解更多关于Eclipse应用程序中的线程的信息,请查看调试视图中的堆栈(在调试模式下)。第一个被称为Main的线程是UI线程。

0

你应该使用 Display.getDefault().asyncExec() 或 Display.getDefault().syncExec()。

示例代码:

@PostConstruct
public void createControls(Composite parent) {
   .... \\ label definition
}
public void updateInterface(String message)
    {
        try{
            Display.getDefault().asyncExec(new Runnable() {
              @Override
              public void run() {
                 try{
                        label.setText(message);  
                    }
                    catch(Exception exc){
                        System.out.println(exc);
                    }               
              }
            });
        }
        catch(Exception exception){
            System.out.println(exception);
        }   
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接