Eclipseでウィザードで何かする必要があるので、JDTでウィザードを実装した方法をチェックして、わからないこの奇妙なコードを見つけました。Eclipse(JDT) - ウィザードのperformFinishメソッド
すでに実行中のジョブからコードが呼び出された場合(そのジョブのスケジューリングルールを使用する場合)、ウィザードのスケジューリングルール(getSchedulingRuleから返されます)は無視されます。したがって、ウィザードがワークスペース全体のスケジューリングルールを必要とするが、現在のスレッドがすでにジョブを実行している場合、代わりにこのジョブのスケジューリングルールが使用されます。これにより、新しいランナブルがワークスペースで実行されるときに問題が発生する可能性があります。私はコードにいくつかのコメントを追加しましたので、より明確です。
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;
}
現在のジョブがたとえばプロジェクトAで操作するルールを持っていて、ウィザードで作業スペース全体を操作するルールが必要な場合、コードが現在のジョブのルールを使用する場合は機能しません(ルールでは、プロジェクトAでは、ウィザードはワークスペース全体のルールを必要とします) – Krab
これはUIスレッドで実行されているため、他のタスクによって起動されたUIジョブが実行を終了するまで、ウィザードは開始できません。だから私は、ウィザードによって開始されたものだけが現在の仕事になる可能性があると思う。おそらく、ウィザードは適切なルールを持つものだけを使用します。 –
ああ、今私は理解していると思う、ありがとう – Krab