以编程方式重试失败的工作项更新

时间:2015-05-05 16:16:50

标签: c# tfs tfs-sdk tfs-workitem

我有一个TFS ISubscriber实现,用于修改WorkItemChangedEvent上的工作项。由于与TFS Build的争用,有时我们会得到ItemAlreadyUpdatedOnServerException,将工作项与构建相关联。

虽然事件处理程序更新了多个工作项字段,但只有在更新历史记录字段时才会发生冲突。我们正在使用WorkItem.Save(SaveFlags.MergeAll)来保存工作项。

我想尝试在此特定方案中重试工作项更新。花了很多时间思考这个并看看API中可能的内容,我能想到的最好的是:

  1. 致电WorkItem.Save(SaveFlags.MergeAll)
  2. 抓住ItemAlreadyUpdatedOnServerException,然后抓住阻止块
  3. 在未能保存的工作项上查询并存储Fields而非IsDirty的所有IsComputed
  4. 使用WorkItem.SyncToLatest()
  5. 将工作项重新同步到最新版本
  6. 重新应用在步骤3中标识为脏的Field值。
  7. 再次尝试保存
  8. 我有理由相信这是可行的,但我想知道是否有任何我错过的内容或者是否有更好的TFS API原生解决方案?

    (抱歉没有代码,我可以在桌面上更新并提供样本)

1 个答案:

答案 0 :(得分:0)

我选择了我在原始问题中概述的实现,它似乎运行良好。以下是重试逻辑的示例实现,该实现是从ItemAlreadyUpdatedOnServerException异常的catch块调用的:

private void RetryWorkItemSave(WorkItem workItem)
{
        //Get the non-computed dirty fields from the failed update
        var dirtyFields = workItem.Fields.Cast<Field>()
                  .Where(w => w.IsDirty && !w.IsComputed)
                  .ToDictionary((f) => f.ReferenceName, (f) => f.Value); 

        //Sync the work item to the latest version
        workItem.SyncToLatest();

        //Reapply the original field changes
        foreach (var field in dirtyFields)
        {
            if (workItem.Fields[field.Key].IsEditable)
            {
                workItem[field.Key] = field.Value;
            }
        }

        workItem.Save(SaveFlags.MergeAll);
}