Friday, May 4, 2012

This task is currently locked by a running workflow and cannot be edited

Upgrading SharePoint workflow is simple, run stsadm- upgradesolution command like any other solution in SharePoint. However you need to know that it can affect existing in progress workflows. I learned it the hard way. Here is what happened, I developed a workflow using Visual Studio and deployed to production after testing. Now after a few weeks I was asked to fix some bugs and add some minor functionality to it. I did that in a few hours, tested and then deployed to production. All the newly created workflows worked fine but “some” of the in progress workflows’ tasks started throwing out “This task is curently locked by a runnign workflow and cannot be edited”. Googling this error pointed to some interesting articles on what causes it. From what i read the root cause is that the SPListItem[SPBuiltInFieldId.WorkflowVersion]!=1, this article seems to solve it by programmatically making it equal to 1 as can be seen here:

http://geek.hubkey.com/2007/09/locked-workflow.html

I tried it but it didnt work for me, although the WorkflowVersion was equal to 1 after running the code mentioned.

Similar articles on this topic leads me to believe that this error is caused by de-serialization of a workflow that has been saved in the database. Since this in progress workflow was created by the older dll/code which is serialized when hydarting the workflow, when the user tries to update the task it deserializes this workflow but since the code has been updated its not able to do it and hence think the current action is not perfomed by the workflow that serialized this orginally. 
So if you want to update workflows in the future you have the following options:
1. Terminate in progress workflows and start again
2. Let in progress workflows to complete before upgrading solution
3. Version your workflows manually by changing the GUID and changing its name , lets say “_v2″ etc. So basically making a new workflow with a different name and attach to the list. Also making sure that the existing workflow is allowed to complete which can be done by going to “List Settings”->Workflow Settings->”Allow New Instances” set to “No”. I see something similar used by Nintex if you ever update the workflow from GUI you will versions of workflow automatically set to not allow new instances of pervious workflows.

Issue and Solution for Custom Wrokflows
SPException: This task is currently locked by a running workflow and cannot be edited”
Root cause: issue has occurred whenever a task has been altered. If a workflow is ‘waiting’ for an event from this task, it will be ‘locked’ and unchangeable until the workflow has a change to process this event.
Solution (work-around 1): Using the below code snippet you can find out the workflow status and can do the necessary action.


SPWorkflowCollection wfs = item.Workflows;
foreach(SPWorkflow wf in wfs)
{
if (
wf.InternalState.ToString() != "Locked, Running")
{
// alter the task here
}
}
If we are trying to change the status of workflow from outside the workflow this error will throw, In this case I had used a custom aspx page to do that. So, in order to avoid that locking exception, before changing the status find out the status of the workflow whether it is locked status or not and make the changes.
Solution (work-around 2): Make the alteration task not synchronous and make the NonSerialaized SP objects
If we use some objects like SPWeb,SPUser, it has to be NonSerializable. So we have to make those type of objects in the SharePoint workflow code as NonSerializable by adding the [NonSerialaized()] attribute on top of the declarations.
Eg:if you are using a SPWeb and SPUser as like this
private SPWeb oWeb = null;
private SPUser oUser = null;
then you can make those objects as NonSerialized like below,
[NonSerialized()]
private SPWeb oWeb = null;
[NonSerialized()]
private SPUser oUser = null;
Also, one more important change you have to make is synchronization = false while altering the task.
if we alter the task like this SPWorkflowTask.AlterTask(oTaskListItem, oTaskHash, true);, the third parameter represents a Boolean variable denotes synchronization is true or false. If we make it as true, it will make immediate modification on task (it mightcreate this locking issue) and if make it as false then it will depend on the timer activity and later it will be modified.
So if we get this error message, make the synchronization parameter as false. like below
SPWorkflowTask.AlterTask(oTaskListItem, oTaskHash, false);


No comments:

Post a Comment