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.
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 operation, read 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.