我有一个方法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()
方法创建新工作之前做出决定吗?
提前致谢!
答案 0 :(得分:1)
创建Job
时,您可以添加IJobChangeListener
以获得有关作业状态的通知:
targetJob.addJobChangeListener(listener);
侦听器有一个done
方法,在作业完成时调用。
当作业被调度并由作业更改侦听器“完成”方法清除时,您将需要设置“作业处于活动状态”标志。菜单处理程序必须检查此标志。
答案 1 :(得分:0)
我使用java.util.concurrent.locks.ReentrantLock
来解决我的问题。谢谢!