在运行作业时将消息提供给用户

时间:2013-10-22 14:29:56

标签: eclipse-plugin eclipse-rcp eclipse-cdt jobs

我有一个方法buildTargets(),当用户点击其中一个UI菜单操作时会调用该方法。

static public void buildTargets(Shell shell, final IMakeTarget[] targets) {
        saveAllResources(targets);
        Job targetJob = new Job(MakeUIPlugin.getResourceString("TargetBuild.backgroundTask.name")) { //$NON-NLS-1$
            @Override
            protected IStatus run(IProgressMonitor monitor) {
                monitor.beginTask(MakeUIPlugin.getResourceString("TargetBuild.monitor.beginTask"), targets.length); //$NON-NLS-1$
                try {
                    for (int i = 0; i < targets.length; i++) {
                        final IMakeTarget target = targets[i];
                        IWorkspaceRunnable runnable = new IWorkspaceRunnable() {

                            public void run(IProgressMonitor monitor) throws CoreException {
                                target.build(new SubProgressMonitor(monitor, 1));                               
                            }
                        };

                        MakeUIPlugin.getWorkspace().run(runnable, null, IResource.NONE, new SubProgressMonitor(monitor, 1));
                    }
                } catch (CoreException e) {
                    return e.getStatus();
                } catch (OperationCanceledException e) {
                } finally {
                    monitor.done();
                }
                return Status.OK_STATUS;
            }

            @Override
            public boolean belongsTo(Object family) {
                return ResourcesPlugin.FAMILY_MANUAL_BUILD == family;
            }           
        };

        // workaround for bug 270326, initialize CUIPlugin preference store to avoid race condition
        CUIPlugin.getDefault().getPreferenceStore().getString("dummy"); //$NON-NLS-1$
        targetJob.schedule();

    }
}

当用户再次单击相同类型的操作时,它会在运行第一个操作时忽略第二个请求。这是我的要求,我认为IWorkspace.run()方法正在这样做(据我所知)。第二个操作是执行除IWorkspace.run()方法之外的所有代码。

我尝试过添加一个监听器。

targetJob.addJobChangeListener(new JobChangeAdapter() {
public void done(IJobChangeEvent event) {
    if (event.getResult().isOK())
       System.out.println("Job completed successfully");
    else
       System.out.println("Job did not complete successfully");
    }
 });

targetJob.setSystem(true);

但是当我在运行第一个作业时第二次单击菜单操作时,我的execute()处理程序方法仍然调用buildTargets()并执行所有代码而不运行IWorkspace.run()方法。我的控制台打印结束s.o.p.第二次点击后“作业成功完成”。

因此,如果用户第二次点击相同的操作,我想向用户说明等待上一个作业完成。我怎么知道第一份工作的状态,以便我可以发消息?我想我需要在buildTargets()方法创建新工作之前做出决定吗?

提前致谢!

2 个答案:

答案 0 :(得分:1)

创建Job时,您可以添加IJobChangeListener以获得有关作业状态的通知:

targetJob.addJobChangeListener(listener);

侦听器有一个done方法,在作业完成时调用。

当作业被调度并由作业更改侦听器“完成”方法清除时,您将需要设置“作业处于活动状态”标志。菜单处理程序必须检查此标志。

答案 1 :(得分:0)

我使用java.util.concurrent.locks.ReentrantLock来解决我的问题。谢谢!