1

背景

我正在通过 Eclipse PDE 开发一个插件,我在创建标记时遇到了生成过多 ResourceChangeEvents 的问题(每次调用 setAttribute(..) 和 file.createMarker(..) 都会生成一个更改事件,所以我想将所有代码简化为单个更改事件)。因此,我正在尝试使用 IWorkspaceRunnable 对工作区进行一组更改。

问题

我想等到 workspace.run(..) 完成后再返回我的变量“MarkerField.marker_”(否则我将返回“null”)。例如,如果我使用 Eclipse 的作业管理器,我可以使用 Job.join() 让我的调用线程等待作业完成。那么,有没有办法让调用线程等到 workspace.run(..) 完成?

// Generates and returns a marker given absolute position
public static IMarker generateMarker(final IFile file, final String message, final        String markerType,
                                     final int severity, final int priority, final int start,
                                     final int end) 
throws CoreException, BadLocationException,
    IOException
{
    // Setting up "line" for marker generation.
    final int line = ResourceUtility.convertToDocument(file).getLineOfOffset(start);

    IWorkspace workspace = ResourceUtility.getWorkspace();

    IWorkspaceRunnable operation = new IWorkspaceRunnable()
    {

        public void run(IProgressMonitor monitor) throws CoreException
        {
            // Marker generation code...
            IMarker marker = file.createMarker(markerType);

            marker.setAttribute(IMarker.MESSAGE, message);
            marker.setAttribute(IMarker.PRIORITY, priority);
            marker.setAttribute(IMarker.LINE_NUMBER, line + 1);
            marker.setAttribute(IMarker.CHAR_START, start);
            marker.setAttribute(IMarker.CHAR_END, end);
            marker.setAttribute(IMarker.SEVERITY, severity);

            MarkerField.marker_ = marker;
        }
    };
    workspace.run(operation, null);

    // Check/wait until the thread is finished.
    return MarkerField.marker_; //I want to ensure this is non-null!
}

// Wrapper class to return marker instance in generate marker methods
// Effectively works as a pointer to a pointer
static class MarkerField 
{
    @SuppressWarnings("null") public static IMarker marker_;
}
4

2 回答 2

2

org.eclipse.core.resources.WorkspaceJob是一个特殊版本,Job其中包括工作区调用以减少资源更改事件的数量。为此,您覆盖runInWorkspace方法而不是普通的run.

如果你使用这个,你可以使用join(也看看JobManager.join哪个允许你等待一系列工作并有一个进度监视器)。

于 2013-09-12T06:38:26.000 回答
1

好问题,@greg-449 有正确的答案,但如果有人正在寻找可以使用的东西IProgressService(就像我一样),你可以替换

IRunnableWithProgress op = new IRunnableWithProgress() {
  public void run(IProgressMonitor monitor) throws InvocationTargetException {
     ...
  }
}

IRunnableWithProgress op = new WorkspaceModifyOperation() {
  public void execute(IProgressMonitor monitor) throws InvocationTargetException {
      ...
  }
}

即:创建一个匿名类的实例,扩展WorkspaceModifyOperation并实现execute而不是run. 结果仍然可以作为IRunnableWithProgress对象接受。

于 2014-02-01T20:52:45.923 回答