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

转自:http://blogs.code-counsel.net/Wouter/Lists/Posts/Post.aspx?List=c04a88a9%2Dd138%2D4ac3%2Da2bb%2Db95c9fdd114e&ID=118

SPWorkflow.AlertTask()的时候出现“This task is currently locked by a running workflow and cannot be edited”错误

A not so uncommon error that people encounter with SharePoint workflow is running into locked tasks. You know, the error that you get when working with workflow tasks, usually on your developer machine. You might get the error message "This task is currently locked by a running workflow and cannot be edited.".

Why do I know it is not uncommon? Well, if you use my common-o-meter you'll see for yourself:

That is a lot of hits!

So many people have this issue with task locking. Generally it goes like this. A developer creates a workflow that issues a couple of tasks. Next the developer fiddles with his code to get it right. Then, returning to his test workflow, he finds that when editing a task and clicking Ok, the SharePoint UI informs him of the fact that the task is locked and cannot be edited.

So, what is going on here? There are a number of items that show up searches for this error message, but never a good explanation on why you got there in the first place. More symptom management that bug fixing! Well, the first thing to note is that the error is absolutely correct. The task is locked, but why is it locked, and was it not unlocked appropriately? Despite what many people think this has nothing to do with your DLL versions, at least not as directly as you might find written and guessed at. Here's the story.

How workflow tasks are locked

The first thing to realize is that when SharePoint workflows alter tasks there needs to be some sort of locking behavior on tasks so that you will not accidentally create race conditions and update a task simultaneously, the one update overwriting the other. Typically database level locks are used but for SharePoint Workflow tasks however a more simple, business-layer type lock suffices. Since SharePoint workflow is about humans and not about maximum near real-time performance the chance of collisions is low enough not to be worried about this. The workflow runtime in SharePoint locks tasks by setting a field and persisting that to the database. It then checks on the field value to determine whether it is locked. You can actually see the code that does this. The SPWinOEItemEventReceiver implements the ItemUpdating and ItemUpdated events. In the ItemUpdating you can find code similar to the following pseudo code

if WorkflowVersion for item not equal to 1
throw locked error
else
Place lock (Set WorkflowVersion on item to value not equal to 1)

How the lock placement is actually implemented is that the WorkflowVersion is set to the value in _UIVersion, which contains a value indicating the major / minor version of the task. Why _UIVersion? It ties the lock to a specific version of the list item, and versioning is enabled on workflow task lists. This probably allows the locks to be bypassed by other code inside SharePoint depending on the version. (By the way: do *not* use this knowledge of internals in production code)

The next interesting question is where the lock is released. The ItemUpdated event facilitates this. When the task lock is detected in the ItemUpdated event it is routed to the SPWorkflowManager. This manager runs code to dehydrate and startup the workflow (which was persisted to the database while waiting for the task change to occur). The SPWorkflowManager uses the SPWinOeHostServices workflow service to unlock the task in the PostWorkItemDequeue method and runs the workflow.

Running into the locking issue

So, the issue is that the lock is still there even though it should have been released in the ItemUpdated event. Clearly, the ItemUpdated event is where the issue lies, and like all bugs in life, you did it, and not the framework! (hope that does not come as a shocker to you) There is only one aspect of the locking that you can control, and that is the persistence and hydration of your workflow to and from the database. This is exactly what is causing the bugs. When the ItemUpdated event fires and tries to de-serialize your workflow there might be an exception during the hydration of your workflow object. This error is difficult to see since it is happening in non-user code based on an asynchronous event. When that error occurs, the task unlocking code does not run!

The general flow of events to create this issue goes something like this.

  • Developer designs a workflow which creates a task.
  • Developer tests the workflow, and runs it up to the task change activity, meaning that the workflow is now serialized in the database waiting for a task change to occur.
  • Developer spots a bug, and updates the workflow in such a way that de-serialization breaks.
  • Developer updates the task through the browser to continue the workflow .
  • Runtime bumps into the de-serialization error, and cannot continue, hence the task unlocking code does not run, and the task is locked for all eternity.

A common de-serialization issue that you might create is a change in the activity structure, or the addition of control fields in your main workflow class. 

Preventing the locking issue

Now that we have a clear understanding of the issue, there are many things you can about it. On development I'd go for re-running the entire workflow (at least when it is not too big).

On Production, it is even easier:

DO NOT UPGRADE UNTIL ALL RUNNING WORKFLOWS ARE COMPLETE

You should quiesce a workflow and when all running workflows have completed, update. Or, when you need to have the business logic available during the quiescing, you can only create a new workflow.

Hope it helps!

Posted at 11:50 AM by Wouter van Vugt | Permalink | Email this Post | Comments (0)

Locked Workflow

I've periodically come across this SPException: "This task is currently locked by a running workflow and cannot be edited" when using the SPWorkflowTask.AlterTask method, even when it seems that the workflow is not in fact locked, and is instead patiently listening for an OnTaskChangedEvent. It turns out that this exception is thrown when the WorkflowVersion of the task list item is not equal to 1, which, if you believe the error message is the same thing as checking to see if the workflow is locked. Only it isn't - apparently sometimes at least, the Workflow version is non zero and the workflow is not locked (the InternalState flag of the workflow does not include the Locked flag bits). I'm not sure why this is occurring - maybe the error message is misleading - but the following code demonstrates a dodgy sort of a workaround that I've found useful. I've no idea if this is a good idea or not, so please treat with skepticism...

代码

using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Workflow;
using System.Collections;
using System.Threading;
namespace DevHoleDemo
{
public class WorkflowTask
    {
public static bool AlterTask(SPListItem task, Hashtable htData, bool fSynchronous, int attempts, int millisecondsTimeout)
        {
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]);
for (int i = 0; i < attempts; i++)
                {
                    SPWorkflow workflow = parentItem.Workflows[new Guid(task[SPBuiltInFieldId.WorkflowInstanceID].ToString())];
if (!workflow.IsLocked)
                    {
                        task[SPBuiltInFieldId.WorkflowVersion] = 1;
                        task.SystemUpdate();
break;
                    }
if (i != attempts - 1)
                        Thread.Sleep(millisecondsTimeout);
                }
            }
return SPWorkflowTask.AlterTask(task, htData, fSynchronous);
        }
    }
}

 

Anonymous said...

Thank you so much for the tip, your code did the trick. I think the reason WorkflowVersion changes is because there's a different version of the workflow dll. So when you recompile your workflow and DLL is changed in the GAC while there are still running workflows, trying to finish any of those workflows might give you "This task is currently locked.." error.

This task is currently locked by a running workflow and cannot be edited的更多相关文章

  1. Creating a SharePoint Sequential Workflow

    https://msdn.microsoft.com/en-us/library/office/hh824675(v=office.14).aspx Creating a SharePoint Seq ...

  2. Show All Running Processes in Linux

    ps由于历史的原因,所以很奇特,有些命令必须加"-",比如: ps A 上面的写法是错误的 ********* simple selection ********* ******* ...

  3. Mesos源码分析(14): DockerContainerier运行一个Task

    DockerContainerizer的实现在文件src/slave/containerizer/docker.cpp中   Future<bool> DockerContainerize ...

  4. Task Parallelism

    The Task Parallel Library (TPL) is based on the concept of a task, which represents an asynchronous ...

  5. 《转》深入理解Activity启动流程(四)–Activity Task的调度算法

    本文原创作者:Cloud Chou. 出处:本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--Activity启 ...

  6. 深入理解Activity启动流程(四)–Activity Task的调度算法

    本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--Activity启动的概要流程 深入理解Activity启动流程(二)- ...

  7. Apparatus, system, and method for automatically minimizing real-time task latency and maximizing non-real time task throughput

    An apparatus, system, and method are provided for automatically minimizing Real-Time (RT) task laten ...

  8. 【C# Task】开篇

    概览 在学task类之前必须学习线程的知识. 以下是task命名空间的类的结构图 1.2种任务类型: 有返回值task<TResult> .无返回值task. 2.2座任务工厂 TaskF ...

  9. Upgrade custom workflow in SharePoint

    Experience comes when you give a try or do something, I worked in to many SharePoint development pro ...

随机推荐

  1. Sidekiq任务堵塞问题

    今天发现服务器上的sidekiq 线程全忙.队列里任务积累了好多. sidekiq里的任务基本都是爬虫脚本,都需要请求外部网站.但是有些网站的响应时间或者读取时间太久,一直一直卡在那里.使得后面的任务 ...

  2. 谷歌正式发布Google APIs Client Library for .NET

    好消息,特大好消息! 英文原文:Google API library for .NET paves the way for Google services on Windows phone 本月 17 ...

  3. 爬虫技术 -- 进阶学习(九)使用HtmlAgilityPack获取页面链接(附c#代码及插件下载)

    菜鸟HtmlAgilityPack初体验...弱弱的代码... Html Agility Pack是一个开源项目,为网页提供了标准的DOM API和XPath导航.使用WebBrowser和HttpW ...

  4. Web开发入门疑问收集(不定期更新)

    bootstrap container和container-fluid的区别 原始链接 container 根据显示设备满足的最小宽度,来决定实际内容宽度,是一个根据设置内容阶梯式响应的布局. 例子: ...

  5. git分享(一)git clone

    git clone 命令参数: usage: git clone [options] [--] <repo> [<dir>] -v, --verbose be more ver ...

  6. 伸展树(一)之 图文解析 和 C语言的实现

    概要 本章介绍伸展树.它和"二叉查找树"和"AVL树"一样,都是特殊的二叉树.在了解了"二叉查找树"和"AVL树"之后, ...

  7. HMM 自学教程(七)前向后向算法

    本系列文章摘自 52nlp(我爱自然语言处理: http://www.52nlp.cn/),原文链接在 HMM 学习最佳范例,这是针对 国外网站上一个 HMM 教程 的翻译,作者功底很深,翻译得很精彩 ...

  8. 充实你的素材库!10款免费的 PSD 素材下载

    由于网页设计师没有时间来自己从零开始设计,所以在设计项目中使用网络上已有的设计素材是常见的方式.这就是为什么我们经常会到网上搜索可以免费下载的素材. 今天,我们这里有几套不同的免费的 PSD 素材分享 ...

  9. 开源一个基于天天团购的团购app

    可能大家都知道天天团购开源系统,一个做团购的开源项目很赞,前些日子做了基于天天团购系统做的团购客户端和移动端服务器!源代码放出,有了解的可以看看,希望收益! 先说服务器:app的服务器,基于天天团购的 ...

  10. 对象Transform,对属性赋值

    private void ContructRequest(Dictionary<string, string> dictionary, CustomerSearchRequest requ ...