Прерывание параллельных задач в процессе
В данной статье рассмотрены примеры реализации параллельных задач с возможностью прерывания одной ветки потока работ.
На практике иногда встречаются бизнес-процессы, в которых работы, например, подготовка командировочных документов, ведутся одновременно с проведением выплаты командировочных. При этом следует учесть возможность отказа в выплате, в результате чего следует прервать подготовку документов.
В некоторых случаях, требуется реализовать прерывание одинаковых параллельных задач при выполнении одной из них. В большинстве случаев такая задача реализуется механизмом "Кто первый", подробнее о данном механизме см. соответствующую страницу справки.
Прерывание одной из параллельных веток потока работ в процессе
Рассмотрим пример с параллельной выплатой денежных средств и подготовкой командировочных документов.

В случае отказа в выплате выполняется сценарий "Прервать подготовку", который снимает текущую активную задачу и присваивает контекстной переменной "Прервать задачи" значение Истина.
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 мин, то раз в минуту будет выполняться данный сценарий и если Прервать задачи = ИСТИНА, выполнение задачи будет прервана.