I've been investigating the Windows Workflow Platform for the last two weeks and have really been pushing it to it's limits with regards to custom State Workflows and persisting it to the database. Great introduction article on State Machines in Windows Workflow and this one on the Base Activity's and this on switching on SQL Persistance.
We've been looking into the migration of existing instances from a custom made .Net workflow engine into a new M$ WF runtime instance and persisting this off to SQL 2005 database.
One issue with the migration is when you set the state where there is a Delay Activity, the instance would have alraedy been in this state for a particular time and the TimeoutDuration will have be reduced. Using the InitializeTimeoutDuration Handler on the DelayActivity in the Workflow you can write some custom code that will be fired that can adjust the TimeoutDuration when it enters that Activity.
private void delayActivity1_InitializeTimeoutDuration(object sender, EventArgs e)
{
(sender as DelayActivity).TimeoutDuration = new TimeSpan(0, 1, 0);
}
One other issue that I am yet to resolve is if you wish to query the instance and see how long there is left on the TimeoutDuration. This function must be there but not quite sure where to find it. I've used the SqlTrackingWorkflowInstance and can't see any public properties that are relevant to this.
I've posted something in the MSDN forums hoping for a reply.
UPDATE
Okay, so the way to get the information is as follows:
StringBuilder strReturn = new StringBuilder();
IEnumerable<SqlPersistenceWorkflowInstanceDescription> foo = servState.GetAllWorkflows();
foreach (SqlPersistenceWorkflowInstanceDescription s in foo)
{
strReturn.AppendFormat("\r\n====================================================================");
strReturn.AppendFormat("\r\nNextTimerExpiration: {0}", s.NextTimerExpiration.ToString());
strReturn.AppendFormat("\r\nStatus: {0}", s.Status.ToString());
strReturn.AppendFormat("\r\nSuspendOrTerminateDescription: {0}", s.SuspendOrTerminateDescription);
strReturn.AppendFormat("\r\nIsBlocked: {0}", s.IsBlocked.ToString());
strReturn.AppendFormat("\r\nWorkflowInstanceId: {0}", s.WorkflowInstanceId.ToString());
}
return strReturn.ToString();
The only danger of this is that if you have 250,000 workflow instances in your runtime, this will cause a performance hit...still investigating whether you can simply call for the SqlPersistenceWorkflowInstanceDescription on a given WorkflowInstanceId. The other problem is that it appears only to show the Next Timer Expiration as apposed to all the timers currently on that WorkflowInstanceId...which is possible with parallel states etc.
Waiting for a reply...