Visual studio 2010 从客户端对象模型更新ListItem未触发OnWorkflowItemChanged活动

Visual studio 2010 从客户端对象模型更新ListItem未触发OnWorkflowItemChanged活动,visual-studio-2010,sharepoint-2010,sharepoint-workflow,workflow-activity,sharepoint-clientobject,Visual Studio 2010,Sharepoint 2010,Sharepoint Workflow,Workflow Activity,Sharepoint Clientobject,使用客户端对象模型在文档库中创建文件时遇到困难。我的自定义Visual Studio 2010工作流未检测到我在创建文件后对其列表项所做的更新 我想介绍一下基础设施,以回答一些可能的问题: 文档将上载到web服务,该服务负责将文档实际插入库中并配置其列表列的值 web服务正在使用客户端对象模型执行此操作 web服务正在使用为商业智能自动化创建的帐户对SharePoint网站进行身份验证,该帐户在与SharePoint交互时不作为系统帐户运行;但是,它是SharePoint所有者的成员 自定义工

使用客户端对象模型在文档库中创建文件时遇到困难。我的自定义Visual Studio 2010工作流未检测到我在创建文件后对其列表项所做的更新

我想介绍一下基础设施,以回答一些可能的问题:

  • 文档将上载到web服务,该服务负责将文档实际插入库中并配置其列表列的值
  • web服务正在使用客户端对象模型执行此操作
  • web服务正在使用为商业智能自动化创建的帐户对SharePoint网站进行身份验证,该帐户在与SharePoint交互时不作为系统帐户运行;但是,它是SharePoint所有者的成员
  • 自定义工作流中的操作取决于文件的列表项列是否已填充,然后才能继续将任务分配给其中两列中的用户;因此,我创建了一个While活动来监视列表项中的更改,直到这两列不再为null
下面是web服务正在做的一个示例。它以商业智能用户身份在IIS中运行。我已经添加了一些注释,以说明我预期工作流会对哪些操作做出适当的响应

Using client As New ClientContext(My.Settings.SharePointSiteURL)

    // Pre-processing to determine appropriate user ID values for columns

    Dim fci As New FileCreationInformation() With {
        .Content = IO.File.ReadAllBytes(storagePath),
        .Overwrite = True,
        .Url = String.Format("{0}/{1}", theList.RootFolder.ServerRelativeUrl, theFileName)
    }

    Dim theFile As Microsoft.SharePoint.Client.File = theList.RootFolder.Files.Add(fci)

    // Expecting the workflow to be activated here
    client.ExecuteQuery()

    theFile.ListItemAllFields("Project_x0020_Manager") = pmId
    theFile.ListItemAllFields("Project_x0020_Accountant") = paId
    theFile.ListItemAllFields.Update()

    // Expecting the onWorkflowItemChanged activity to be invoked here
    client.ExecuteQuery()
End Using
上载文件并继续等待来自SharePoint的更改事件时,工作流确实会激活,但该事件从未作为web服务操作的直接结果出现。我可以手动修改项目,并成功地继续


在使用客户端对象模型时,是否考虑到可能会阻止这些事件正常触发?

看起来像是某种奇怪的竞争条件。我可以通过一些示例代码部分重现您的问题:

using (var client = new ClientContext(ConfigurationManager.AppSettings["Site"]))
{
    client.Load(client.Site);
    client.Load(client.Site.RootWeb);
    var list = client.Site.RootWeb.Lists.GetByTitle("Shared Documents");
    client.Load(list);
    client.Load(list.RootFolder);
    client.ExecuteQuery();
    var fci = new FileCreationInformation()
              {
                  Content = File.ReadAllBytes(ConfigurationManager.AppSettings["File"]),
                  Overwrite = true,
                  Url = list.RootFolder.ServerRelativeUrl + "/" + "file.xml"
               };
    var file = list.RootFolder.Files.Add(fci);
    client.ExecuteQuery();

    //If following 3 lines are commented out, problem you described may or may not occur. I wasn't able to run into problems, when i loaded file and list item before.
    //client.Load(file);
    //client.Load(file.ListItemAllFields);
    //client.ExecuteQuery();

    //Problem also doesn't occur, when i put here
    //System.Threading.Thread.Sleep(1000); 

    //If code just runs here without delay, sometimes i run into issue you described. 
    var itm = file.ListItemAllFields;
    itm["SampleColumn"] = "Test content!";
    itm.Update();
    client.ExecuteQuery();
}
和工作流程:

public Workflow1()
{
    InitializeComponent();
}

public Guid workflowId = default(System.Guid);
public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();

private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
{
    var comment = "Workflow started!, item SampleColumn is: " +
    workflowProperties.Item["SampleColumn"];
    SPWorkflow.CreateHistoryEvent(workflowProperties.Web, WorkflowInstanceId, 0, workflowProperties.Web.CurrentUser, new TimeSpan(), "Update", comment, string.Empty);
}

private void onWorkflowItemChanged1_Invoked(object sender, ExternalDataEventArgs e)
{
    var comment = "Workflow continous!, item Title is: " +                           workflowProperties.Item["SampleColumn"];
    SPWorkflow.CreateHistoryEvent(workflowProperties.Web, WorkflowInstanceId, 0, workflowProperties.Web.CurrentUser, new TimeSpan(), "Update", comment, string.Empty);
 }
以及工作流本身


如果你有不同的想法,请告诉我。我自己在SharePoint library上运行的声明式工作流中遇到了一些问题,大多数时候我都找不到好的解决方案

是工作流在进入睡眠状态后未被触发的问题,还是元数据未在此Web服务中通过COM设置的问题?如果您有第二个问题,这可能会有所帮助?COM正在正确设置列。工作流正在正确启动。问题是,我使用COM设置的列在我的第一个活动中没有值,除非我在激活后立即放置一个While循环,等待OnWorkflowItemChanged活动。但是,COM的更新不会触发该活动,因此工作流不会前进。这实际上与我的构造相同。唯一的区别是,我的工作流中的onWorkflowItemChanged被放置在While活动中,只是为了彻底检查并确保工作流不会继续,直到我检测到的更改显示Project Manager和Project Accounter列不为空。奇怪的是,虽然没有检测到更改事件,但是如果我尝试创建任务并在不等待更改事件的情况下将它们分配给这些列中的用户,那么这些列也可能是空的。比赛结果从来都不一样。我从其他渠道收到类似的反馈,这是一种可能的比赛条件,除了微软之外,任何人都不可能解决。我将把我的数据库逻辑移到工作流本身中,这样它的行为是决定性的,而不是希望等待比赛结束。我将把这个标记为答案。