Прерывание параллельных задач в процессе
В данной статье рассмотрены примеры реализации параллельных задач с возможностью прерывания одной ветки потока работ.
На практике иногда встречаются бизнес-процессы, в которых работы, например, подготовка командировочных документов, ведутся одновременно с проведением выплаты командировочных. При этом следует учесть возможность отказа в выплате, в результате чего следует прервать подготовку документов.
В некоторых случаях, требуется реализовать прерывание одинаковых параллельных задач при выполнении одной из них. В большинстве случаев такая задача реализуется механизмом "Кто первый", подробнее о данном механизме см. соответствующую страницу справки.
Прерывание одной из параллельных веток потока работ в процессе
Рассмотрим пример с параллельной выплатой денежных средств и подготовкой командировочных документов.
В случае отказа в выплате выполняется сценарий "Прервать подготовку", который снимает текущую активную задачу и присваивает контекстной переменной "Прервать задачи" значение Истина.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 ; } } } |
Для работы данного сценария необходимо подключить следующие пространства имен:
1 2 3 4 5 | 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 (Тип – Базовый класс задачи) задачу "Выписать командировочное удостоверение" или "Выписать брони", можно воспользоваться следующим сценарием:
1 2 3 4 5 6 7 8 9 | public override void OnTaskCreate(ITaskBase task, Context context) { //выбираем только нужную задачу по имени операции if ((task.Subject == "Выписать брони" )|(task.Subject == "Выписать командировочное удостоверение" )) { //записываем задачу в контекстную переменную context.TaskToAbort=(TaskBase)task; } } |
Для того, чтобы все последующие после прерванной задача не выполнялась, используется механизм условной операции. Подробнее об этом см. на соответствующей странице справки.
Условие выглядит следующим образом:
1 | Прервать задачи = false |
Имеется более простой вариант прерывания задачи – эскалация по сценарию.
Сценарий проверяет, возвращает значение переменной "Перервать задачи" типа Да/нет. Текст сценария выглядит следующим образом:
1 2 3 4 | public bool CheckMoneyDenied(Context context) { return context.PrepvatjZadachi; } |
В настройках эскалации следует настроить периодичность выполнения данного сценария. Например, если поставить период 1 мин, то раз в минуту будет выполняться данный сценарий и если Прервать задачи = ИСТИНА, выполнение задачи будет прервана.