等待所有提交到SWT UI线程的Runnables与Display :: asyncExec()完成

Juh*_*ala 4 java swt eclipse-rcp

有没有办法等待通过asyncExec(...)提交到SWT UI线程的所有Runnables完成?

背景:

我有一个长时间运行的操作,其中包括触发事件,然后通过Display的asyncExec(...)实例方法将Runnables提交到SWT UI线程.

长时间运行操作的进度显示在ProgressMonitorDialog中,我想仅在UI线程完成Runnables后才关闭对话框.

将调用从asyncExec(...)更改为syncExec(...)不是一个选项,因为当从其他上下文触发事件时,不需要后者.

Pau*_*ter 7

org.eclipse.swt.widgets.Display.readAndDispatch()将处理事件队列中的事件,并false在没有其他事件要处理时返回.但您可能不希望在处理事件时使用它.

asyncExec(*) 是一个FIFO队列(虽然OS图形事件取代了asyncExecs),因此您可以执行大部分长时间运行的op处理,然后在队列中放置最终的asyncExec:

final boolean[] done = new boolean[1];
Runnable r = new Runnable() {
  public void run() {
    done[0] = true;
  }
};
// now wait for the event somehow.  The brute force method:
while (!done[0]) {
  Thread.sleep(200);
}
Run Code Online (Sandbox Code Playgroud)

理论上,从你长时间运行的op中产生的所有其他asyncExecs将在你到达最后一个时完成.

编辑:潜在的其他选择

创建自己的org.eclipse.core.runtime.jobs.Job,然后join()在最后:

public static class RefCountJob extends Job {
    public RefCountJob() {
        super("REF_COUNT");
    }

    int count = 0;

    public void increment() {
        count++;
    }

    public void decrement() {
        count--;
    }

    @Override
    protected IStatus run(IProgressMonitor monitor) {
        monitor.beginTask("WAITING", IProgressMonitor.UNKNOWN);
        while (count > 0) {
            Thread.sleep(200);
            monitor.worked(1);
        }
        monitor.done();
        return Status.OK_STATUS;
    }
}
Run Code Online (Sandbox Code Playgroud)

要使用它,每次你要发射事件时递增()它,并在它们完成时让它们减少它(你必须确保它们减少它而不管抛出什么异常:-)

RefCountJob ref = new RefCountJob();
// ... do stuff, everybody increments and decrements ref
ref.increment();
// ... do more stuff
ref.increment();
// at the end of your long-running job
ref.schedule();
ref.join();
Run Code Online (Sandbox Code Playgroud)

  • 我检查了`Display.asyncExec(Runnable)`并且不保证订单.关于`org.eclipse.swt.widgets.Display.readAndDispatch()`的信息只是表明它还检查并处理来自/ syncExecs的线程间消息.它目前是一个FIFO队列,`org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(boolean)`,但你在技术上是正确的,这不是一个承诺(只是最后7个版本的实现:-) (3认同)