Interrupting parallel tasks in a process

This article offers examples of implementation of parallel tasks, with a possibility to interrupt one of the sequence flows.

In some processes, different activities are executed at the same time. For example, consider a business trip, where all the documents are prepared at the same time as the travel allowance is being paid out. It is important to take into account the possibility to cancel the payment and, therefore, stop the preparation of documents. 

Attention!
Sometimes you need to interrupt similar parallel tasks when one of them is completed. Usually, this is implemented by means of the “First Response” mechanism. You can read more about it in this article.

Interrupting one of the parallel sequence flows

Consider the example of the travel allowance, which is given out at the same time as the travel documents are prepared.

 

If the allowance is denied, the “Interrupt preparation” script is executed. It cancels the currently active task and attributes the True value to the Interrupt Task context variable.

public void AbortTask(Context context)
       {
            
           if (context.TaskToAbort!=null)
           {
               // Get element of the process map
               var element = (BPMNFlowElement)context.TaskToAbort.WorkflowBookmark.Instance.Process.Diagram.Elements.Single(e => e.Uid == context.TaskToAbort.WorkflowBookmark.ElementUid);
                // Search for an outgoing transition by its name. Since there are two 
tasks, search for one of the two corresponding transitions.
                var connector = element.OutputConnectors.FirstOrDefault(c => (c.Name ==
"Next"||c.Name=="Ready"));
               if (connector != null)
              {
                  // Transition found
                  // Form data for task execution
                   var executeData = new WorkflowTaskExecuteData(context.TaskToAbort, connector.Uid);
                   // Execute task
Locator.GetServiceNotNull<IWorkflowRuntimeService>().Execute(executeData);
context.InterruptTasks = true;
               }
           }
       }


For the script to work, add the following namespaces:

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

To write the “Issue business travel form” or the “Book tickets” task to the TaskToAbort context variable (Type – task base class), you can use the following script:

public override void OnTaskCreate(ITaskBase task, Context context)
      {
          //select the required task by operation name
          if ((task.Subject == "Book tickets")|(task.Subject == "Issue business travel form"))
          {
              //write the task to the context variable
              context.TaskToAbort=(TaskBase)task;
          }
      }

If you do not want the tasks that follow the interrupted task to be executed, use a conditional operationread more about it here

The condition looks as follows:

1 Interrupt tasks = false

There is an easier way to interrupt a task: escalation by a script.

 

The script checks and returns the value of the yes/no “Interrupt Task” variable The text of the script is as follows:

public bool CheckMoneyDenied(Context context)
     {
          return context.InterruptTasks;
      }

In escalations settings, set up the periodicity. For example, if you specify 1 minute, then the script will be executed once per minute. If at that moment Interrupt Task = TRUE, the task is interrupted.

This method, however, has one disadvantage: the task is not interrupted immediately, but only when the script is executed according to the timer.