Длительные задания (те, которые выполняются дольше секунды) должны отчитываться о состоянии выполнения в IProgressMonitor. Отчет передается в метод run задания. Все сообщения о состоянии выполнения и части выполненной работы, переданные в этот монитор, отображаются в панели рабочей среды Состояние выполнения.
Монитор состояния выполнения можно также применять для проверки, не было ли из панели Состояние выполнения запросов на отмену. Когда пользователь (или модуль, работающий с API задания) пытается отменить задание, метод isCanceled() класса IProgressMonitor вернет true. Регулярная проверка состояния отмены задания и ответ на запрос отмены выходом из метода run сразу же при обнаружении этого запроса является функцией задания. Ниже приведен метод run, который отчитывается о состоянии выполнения и отвечает на отмену задания:
public IStatus run(IProgressMonitor monitor) { final int ticks = 6000; monitor.beginTask("Doing some work", ticks); try { for (int i = 0; i < ticks; i++) { if (monitor.isCanceled()) return Status.CANCEL_STATUS; monitor.subTask("Processing tick #" + i); //... выполнение некоторых действий ... monitor.worked(1); } } finally { monitor.done(); } return Status.OK_STATUS;
}
Метод beginTask задает имя задачи в соответствующей панели Состояние выполнения и устанавливает общий объем работы, чтобы панель могла просчитать состояние выполнения. Как только работа будет выполнена, в дереве состояния выполнения появятся дочерние сообщения subTask. Панель Состояние выполнения просчитывает и отображает процент выполнения на основе объема работы, полученного из worked.
Как вы уже, вероятно, поняли, класс IProgressMonitor
разработан с поддержкой соответствующего UI. Поддержка предоставлена модулем UI платформы, поэтому состояние выполнения работающих заданий можно увидеть в рабочей среде. Можно помнить об этом при настройке заданий и соответственно управлять их представлением.
Подробнее об API, позволяющих отображать состояние выполнения задания, см. в разделе Поддержка параллелизма в рабочей среде.
Что делать, если ваше задание - это низкоуровневая реализация, подробности которой пользователям видеть вовсе не обязательно? Такое задание можно пометить как системное задание. Системное задание - это почти то же самое, что и обычное задание. Отличие только в том, что его UI не устанавливает панель Состояние выполнения и не показывает никаких других сведений UI, связанных с выполняющимся заданием. Если для вашего задания не требуется инициализация непосредственно пользователем, или если ваше задание не является периодической задачей, настраиваемой пользователем, то задание следует сделать системным. Протокол настройки системного задания прост:
class TrivialJob extends Job { public TrivialJob() { super("Trivial Job"); setSystem(true); } ... }
Вызывать setSystem следует до того, как планировать задание. При попытке вызвать этот метод для ждущего, спящего или выполняющегося задания возникнет исключительная ситуация.
Если ваше задание является длительной операцией, которую должен инициировать пользователь, то его следует пометить как пользовательское задание. Пользовательское задание отображается в модальном окне состояния выполнения с кнопкой для перемещения окна в фон. В рабочей среде предусмотрен параметр для пользователя, который управляет модальностью этих окон. Если задание определено как пользовательское, то окно состояния выполнения будет автоматически подстраиваться под пользовательские параметры просмотра. Протокол настройки пользовательского задания аналогичен:
class TrivialJob extends Job { public TrivialJob() { super("Trivial Job"); setUser(true); } ... }
Вызывать setUser также следует до планирования задания.
Групповое состояние выполнения - это еще один способ управления отображением задания в UI. Если в UI требуется отобразить объединенное состояние выполнения нескольких связанных между собой заданий, то можно создать особый IProgressMonitor для группы связанных заданий. Этот монитор создается с помощью протокола IJobManager. В следующем фрагменте кода показано создание группового состояния выполнения и связывание его с заданием.
... IJobManager jobMan = Platform.getJobManager(); myGroup = jobMan.createProgressGroup(); job.setProgressGroup(myGroup, 600); // указываются единицы работы для отображения job.schedule() ...
Такой прием позволяет разбивать задачи на несколько заданий, но пользователю виден отчет как об одной задаче. Монитор группового состояния выполнения обрабатывает сведения и вычисляет процент выполнения всех заданий группы.
Задание следует помещать в группу до планирования. После завершения выполнения задания его связь с группой теряется. Если задание необходимо запланировать снова, то его придется заново помещать в группу.