Problem: In SharePoint Workflow, "This task is currently locked by a running workflow and cannot be edited" is the common exception, that we face.
Solution:
Generally this exception occurs
1. when the number of items in the Task List gets high
This exception says that the workflow is not able to deliver the all the events at a given time and so the tasks get locked.
Out Of Box, the default event delivery throttle value is 15.
Event delivery throttle value Specifies the number of workflows that can be processed at the same time across all front-end Web servers
look at following link.
(http://blogs.msdn.com/b/vincent_runge/archive/2008/09/16/about-the-workflow-eventdelivery-throttle-parameter.aspx )
If the value returned by query is superior to the throttle (15 by default), any new workflow event will not be processed immediately.
so we need to change it by stsadm command like...
stsadm -o setproperty -pn workflow-eventdelivery-throttle -pv "20"
(http://technet.microsoft.com/en-us/library/cc287939(office.12).aspx )
2. When we modify a Workflow Task from Custom TaskEdit Page.
when we try to modify the workflow task from outside workflow default Page, like custom workflow taskedit page. then is exception occurs.
suppose we have custom task edit page with dropdown and values are submitted/ Progress/ completed etc and we want to complete task from here.
it will throw exception on SPWorkflowTask.AlterTask method, which changes the TaskStatus.
When I debug, to find the root cause I actully found that the workflow is not locked.
The InternalState flag of the workflow does not include the Locked flag bits
(http://msdn.microsoft.com/en-us/library/dd928318(v=office.12).aspx )
When I found this link http://geek.hubkey.com/2007/09/locked-workflow.html
It is exactly what I wanted. It says that "when the WorkflowVersion of the task list item is not equal to 1" then the error occurs. The solution that is propsed here works fantastically
if ((int)task[SPBuiltInFieldId.WorkflowVersion] != 1)
{
SPList parentList = task.ParentList.ParentWeb.Lists[new Guid(task[SPBuiltInFieldId.WorkflowListId].ToString())];
SPListItem parentItem = parentList.Items.GetItemById((int)task[SPBuiltInFieldId.WorkflowItemId]);
SPWorkflow workflow = parentItem.Workflows[new Guid(task[SPBuiltInFieldId.WorkflowInstanceID].ToString())];
if (!workflow.IsLocked)
{
task[SPBuiltInFieldId.WorkflowVersion] = 1;
task.SystemUpdate();
break;
}
}
It will reset the workflow version to 1 again.
Conclusion: This Exception is completely confusing. So, we need to find at first whether our workflow is really locked or not. If it is really locked then use 1st method. If not, then check the workflow version and set it to 1 again.