Thursday, December 1, 2011

Start workflow from timer job

We cannot start workflow automatically when the item is created. We have to select the right workflow dynamically by data in the item. Workflow starts when user clicks the button (SPWorkflowManager.StartWorkflow method is called). Unfortunately, starting the workflow is very slow, so we decided to start it from the timer job. Instead of starting the workflow immediately we only set field "Start Workflow". All items with flag "Start Workflow" are periodically checked every 5 minutes in timer job and workflow is started using the author's account (SPUserToken).

using (SPSite site = new SPSite(webUrl))
{
using (SPWeb web = site.OpenWeb())
{
// Find all items where field StartWorkflow = TRUE
SPListItemCollection items = web.Lists["ListName"].GetItems(...);
foreach (SPListItem item in items)
{
SPUser author = web.AllUsers.GetByID(Utils.GetLookupId(item[SPBuiltInFieldId.Author]));
// Run workflow as item author (CreatedBy)
SPUserToken token = web.AllUsers[author.LoginName].UserToken;
using (SPSite userSite = new SPSite(web.ID, token))
{
SPWorkflowManager manager = site.WorkflowManager;
using (SPWeb userWeb = userSite.OpenWeb())
{
try
{
SPList listAsUser = userWeb.Lists[item.ParentList.ID];
SPListItem itemAsUser = listAsUser.GetItemById(item.ID);

// Find correct workflow association
SPWorkflowAssociation association = listAsUser.WorkflowAssociations[...];
manager.StartWorkflow(itemAsUser, association, association.AssociationData);
}
catch (Exception ex)
{
// Log error...
}
}
}
}
}
}

No comments:

Post a Comment