Прерывание параллельных задач в процессе
В данной статье рассмотрены примеры реализации параллельных задач с возможностью прерывания одной ветки потока работ.
На практике иногда встречаются бизнес-процессы, в которых работы, например, подготовка командировочных документов, ведутся одновременно с проведением выплаты командировочных. При этом следует учесть возможность отказа в выплате, в результате чего следует прервать подготовку документов.
В некоторых случаях, требуется реализовать прерывание одинаковых параллельных задач при выполнении одной из них. В большинстве случаев такая задача реализуется механизмом "Кто первый", подробнее о данном механизме см. соответствующую страницу справки.
Прерывание одной из параллельных веток потока работ в процессе
Рассмотрим пример с параллельной выплатой денежных средств и подготовкой командировочных документов.
В случае отказа в выплате выполняется сценарий "Прервать подготовку", который снимает текущую активную задачу и присваивает контекстной переменной "Прервать задачи" значение Истина.
public void AbortTask(Context context) { if (context.TaskToAbort!=null) { // Получаем элемент диаграммы процесса, по которому сформирована задача var element = (BPMNFlowElement)context.TaskToAbort.WorkflowBookmark.Instance.Process.Diagram.Elements.Single(e => e.Uid == context.TaskToAbort.WorkflowBookmark.ElementUid); // Ищем исходящий переход по его имени. Так как может быть одна из двух задач, ищем соответсвие одному из двух переходов. var connector = element.OutputConnectors.FirstOrDefault(c => (c.Name == "Далее"||c.Name=="Готово")); if (connector != null) { // Переход нашли // Формируем данные для исполнения задачи var executeData = new WorkflowTaskExecuteData(context.TaskToAbort, connector.Uid); // Исполняем задачу Locator.GetServiceNotNull<IWorkflowRuntimeService>().Execute(executeData); context.PrepvatjZadachi = true; } } }
Для работы данного сценария необходимо подключить следующие пространства имен:
using EleWise.ELMA.Tasks.Models; using EleWise.ELMA.Workflow.BPMN.Diagrams.Elements; using EleWise.ELMA.Workflow.Models; using EleWise.ELMA.Workflow.Services; using EleWise.ELMA.Services
Для записи в контекстную переменную TaskToAbort (Тип – Базовый класс задачи) задачу "Выписать командировочное удостоверение" или "Выписать брони", можно воспользоваться следующим сценарием:
public override void OnTaskCreate(ITaskBase task, Context context) { //выбираем только нужную задачу по имени операции if ((task.Subject == "Выписать брони")|(task.Subject == "Выписать командировочное удостоверение")) { //записываем задачу в контекстную переменную context.TaskToAbort=(TaskBase)task; } }
Для того, чтобы все последующие после прерванной задача не выполнялась, используется механизм условной операции. Подробнее об этом см. на соответствующей странице справки.
Условие выглядит следующим образом:
Прервать задачи = false
Имеется более простой вариант прерывания задачи – эскалация по сценарию.
Сценарий проверяет, возвращает значение переменной "Перервать задачи" типа Да/нет. Текст сценария выглядит следующим образом:
public bool CheckMoneyDenied(Context context) { return context.PrepvatjZadachi; }
В настройках эскалации следует настроить периодичность выполнения данного сценария. Например, если поставить период 1 мин, то раз в минуту будет выполняться данный сценарий и если Прервать задачи = ИСТИНА, выполнение задачи будет прервана.