I have set of custom activities, which are used in complex workflows.
I would like to make them (custom activities) persistable without having workflow in an idle state. It should be kind of failover system, so whenever something goes wrong during execution of a workflow it can be either:
I've worked for few days with workflow persistance, but I am not sure if I can achieve my goal with it. Why?
Can you please advice me, it workflow bookmarks are the way to go here?
I see some light in notblocking bookmarks, but I cannot persist them and resume later on. Can you please give me some hints how to persist a nonblocking bookmark for later resume?
Edit:
In wf3 there was an attribute PersistOnClose
which would be enough for my requirement.
in wf4 it was replaced with Persist
activity, which could also be useful, however I do not want to have extra activities in my already complex workflows.
Ideally, it would be great to be able to execute context.RequestPersist(callback)
from NativeActivityContext
, however this method is internal (and everything what is inside it is not visible outside of original assembly.
Here is what I came with:
PersistOnCloseAttribute
is not an option, because I'm using WF4 and this attribute is only .NET 3.x WF.The solution is to use Persist
activity in each custom made activity (has to extend NativeActivity
which can schedule child activities):
//class field
Activity childActivity = new Persist();
In order to make it work, it has to be added to metadata as ImplmentationChild:
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
base.CacheMetadata(metadata);
metadata.AddImplementationChild(this.childActivity);
}
The last thing is to schedule child activity from Execute method (doesn't matter where, persistence will happen only after calling activity is completed*).
protected override void Execute(NativeActivityContext context)
{
//...
context.ScheduleActivity((Activity)this.childActivity);
}
In order keep the workflow persisted after unhandled exception, this piece of code have to be added to WorkflowApplication:
application.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
{
return UnhandledExceptionAction.Abort;
};
*return from the Execute
method doesn't necessarily mean that the activity is "completed" - i.e. there are blocking bookmarks inside activity (see drawbacks below).
There are few drawbacks of this solution: