我需要在Eclipse中使用向导做一些事情,所以我检查了JDT他们如何实现向导并找到了我不理解的奇怪代码。
如果从已经执行的Job调用代码(它使用该Job的调度规则),它将忽略向导调度规则(从getSchedulingRule返回)。因此,如果向导需要整个工作空间的调度规则但当前线程已经在执行任何作业,则会使用此作业的调度规则,这会在工作空间中执行新的runnable时导致问题。我在代码中添加了一些注释,因此更清楚。
任何Eclipse专家都能解释为什么try块按原样实现(不只是使用getSchedulingRule)?
/**
* Returns the scheduling rule for creating the element.
* @return returns the scheduling rule
*/
protected ISchedulingRule getSchedulingRule() {
return ResourcesPlugin.getWorkspace().getRoot(); // look all by default
}
/*
* @see Wizard#performFinish
*/
@Override
public boolean performFinish() {
IWorkspaceRunnable op= new IWorkspaceRunnable() {
@Override
public void run(IProgressMonitor monitor) throws CoreException, OperationCanceledException {
try {
finishPage(monitor);
} catch (InterruptedException e) {
throw new OperationCanceledException(e.getMessage());
}
}
};
try {
//TODO: i need explanation of this block. Wizard should be used
// from UI thread, so the code Job.getJobManager().currentJob()
// means that there is possible Job currently executed by UI thread.
// Ok now if there is a job, use its scheduling rule ignoring getSchedulingRule.
// This could be maybe to force that this new runnable isn't executed until this thread finishes
// its current Job. Okb but if the current Job rule isn't so powerfull as this wizard needs, what than?
// It will cause error when executing op, because the runnable will not have enough access
// cause ignoring getSchedulingRule...
ISchedulingRule rule= null;
Job job= Job.getJobManager().currentJob();
if (job != null)
rule= job.getRule();
IRunnableWithProgress runnable= null;
if (rule != null)
runnable= new WorkbenchRunnableAdapter(op, rule, true);
else
runnable= new WorkbenchRunnableAdapter(op, getSchedulingRule());
getContainer().run(canRunForked(), true, runnable);
} catch (InvocationTargetException e) {
handleFinishException(getShell(), e);
return false;
} catch (InterruptedException e) {
return false;
}
return true;
}
答案 0 :(得分:1)
我不确定我能解释所有这一切,但需要注意的一件事是
Job.getJobManager().currentJob();
仅返回当前主题中的当前作业。由于performFinish
通常在UI线程中运行,因此这不是普通的后台作业。 UIJob
作业在UI线程中运行。在我看来,这个代码试图从某个UI作业中获取该向导或相关代码已经启动的规则。
电话上的true
个参数:
new WorkbenchRunnableAdapter(op, rule, true)
将导致WorkbenchRunnableAdapter
致电
Job.getJobManager().transferRule(fRule, thread);
如果线程发生变化。我认为这意味着代码试图在runnable的执行和以前运行的任何作业中保持使用相同的规则。