roger-castaldo/BPMNEngine

How to execute UserTask?

Closed this issue · 6 comments

use this ? process.CompleteUserTask("UserTask_3", new ProcessVariablesContainer(), "user");

yes its correct but there is a bug at least with me
in this function
private void _MergeVariables(UserTask task, ProcessVariablesContainer variables, string completedByID) { _MergeVariables(task, variables, completedByID); }
you need to cast task to Atask like this
`private void _MergeVariables(UserTask task, ProcessVariablesContainer variables, string completedByID)
{

        _MergeVariables((ATask)task, variables, completedByID);
    }`

then you need to implement process.OnTaskCompleted += OnTaskCompleted; before you can call process.CompleteUserTask

To complete the task, the callback is correct. If you want to intercept the usertask in order to gain the variables container as well as access to the element itself and the callbacks, you would implement the delegate BeginUserTask and assign it to process.BeginUserTask. This will invoke linearly, all On delegates are non-linear as they are event calls to indicate things have been done.

there is a problem, when a UserTask begins. the user may enter some data and complete the task at anytime, maybe several days later. How to restore the process state and continue the UserTask?

XmlDoc docDef;
BusinessProcess bp = new BusinessProcess(docDef);
bp.Suspend();
XmlDoc state = doc.State;

BusinessProcess bp = new BusinessProcess(docDef);
bp.LoadState(state);
bp.Resume();
bp.CompleteUserTask({User task id}, {variables},{completedByID} [optional])

Basically you need to suspend the process (assuming there are other steps you don't want running before unloading the object). Then later on when the user information is ready, create a new instance and load in the previously saved state. Once complete (calling resume if suspend was called before), Invoke CompleteUserTask passing the id of the task in question as well as any variables for the step and the optional userid.

thanks for your answer. But when bp.Resume() is called, bp._isSuspended is false, throw an exception. It seems bp._isSuspended is not restored when bp.LoadState() is called.

public void Resume()
{
_current = this;
WriteLogLine(LogLevels.Info, new StackFrame(1, true), DateTime.Now, "Attempting to resmue Business Process");
if (_isSuspended)
{
_isSuspended = false;
sSuspendedStep[] resumeSteps = _state.ResumeSteps;
_state.Resume();
if (resumeSteps != null)
{
foreach (sSuspendedStep ss in resumeSteps)
_ProcessStepComplete(ss.IncomingID, ss.ElementID);
}
foreach (sStepSuspension ss in _state.SuspendedSteps)
{
Thread th = new Thread(new ParameterizedThreadStart(_suspendEvent));
th.Start((object)(new object[] { ss.id, ss.EndTime }));
}
WriteLogLine(LogLevels.Info, new StackFrame(1, true), DateTime.Now, "Business Process Resume Complete");
}
else
{
Exception ex = new NotSuspendedException();
WriteLogException(new StackFrame(1, true), DateTime.Now, ex);
throw ex;
}
}

patched with new release version 1.4.3.1 to fix the above bug that did not load the suspended information into the business process from the state.