Асинхронное разделение IProgressMonitor

#java #eclipse #eclipse-plugin

#java #затмение #eclipse-плагин

Вопрос:

Я хочу создать свой собственный ISearchQuery , который делегирует фактический поиск паре других поисковых запросов. Я ожидаю, что только один из других поисковых запросов действительно что-то найдет, вот почему я хочу запускать их асинхронно.

Однако я изо всех сил пытаюсь понять, как достичь этой цели. Стандартным способом в Eclipse, вероятно, было бы использование заданий:

 @Override
public IStatus run(final IProgressMonitor monitor) throws OperationCanceledException {
    for (Delegate delegate : delegates) {
        Job job = new Job(delegate.getName()) {

            @Override
            protected IStatus run(IProgressMonitor monitor) {
                delegate.run(monitor);
                return Status.OK_STATUS;
            }
        };
        job.schedule();
    }
    return Status.OK_STATUS;
}
 

Это нормально асинхронно, но проблема здесь в том, что, поскольку каждое задание имеет свое собственное IProgressMonitor , родительский поиск не может получить никакой информации о том, как продвигается прогресс (за исключением «завершено», когда задание выполнено). Кроме того, я не уверен, выполняются ли эти задания вообще одновременно, судя по тому, что я видел, обычно они выполняются одно за другим.

Я нашел субмонитор, и он выглядит многообещающим:

 @Override
public IStatus run(final IProgressMonitor monitor) throws OperationCanceledException {
    SubMonitor subMonitor = SubMonitor.convert(monitor, delegates.size());
    for (Delegate delegate : delegates) {
        SubMonitor delegateMonitor = subMonitor.split(1);
        delegate.run(delegateMonitor);
    }
    return Status.OK_STATUS;
}
 

Однако сейчас я пытаюсь понять, как заставить это работать асинхронно.

Я мог бы объединить оба этих подхода, игнорируя работу IProgressMonitor , но это похоже на обман.

Каков наилучший способ разделить a IProgressMonitor на асинхронные задачи?

Ответ №1:

Я сам не сталкивался с такой ситуацией, поэтому мои мысли не подкреплены практическим опытом.

Моим первым выбором было бы запланировать одно задание и использовать один монитор выполнения для всех асинхронных задач. Задаче будет разрешено сообщать только об объеме выполненной работы (т. Е. Вызов worked() ). beginTask() и done() будет вызываться только из задания, как показано в вашем втором фрагменте.

За исключением FutureProgressMonitor , ни одна из IProgressMonitor реализаций, с которыми я столкнулся, не кажется потокобезопасной.

Следовательно, вам нужно будет реализовать потокобезопасную оболочку. или посмотрите FutureProgressMonitor , подходит ли это.

Кроме того, задание должно было бы дождаться завершения всех задач. Возможно, метод возвращения Job.ASYNC_FINISH с задания run() тоже работает, но я сам пока им не пользовался.