以编程方式重试失败的工作项更新
Programmatically retrying a failed work item update
我有一个 TFS ISubscriber
实现可以修改 WorkItemChangedEvent
上的工作项。由于与 TFS 构建将工作项与构建相关联的争用,我们有时会收到 ItemAlreadyUpdatedOnServerException
。
虽然事件处理程序更新了几个工作项字段,但冲突仅发生在更新历史字段时。我们正在使用 WorkItem.Save(SaveFlags.MergeAll)
来保存工作项。
我想尝试在此特定情况下重试工作项更新。花了相当多的时间思考这个问题并研究了 API 中的可能性,我能想到的最好的办法是:
- 致电
WorkItem.Save(SaveFlags.MergeAll)
- 捕获
ItemAlreadyUpdatedOnServerException
然后在 catch 块中
- 查询并存储所有
Fields
IsDirty
而不是 IsComputed
在保存失败的工作项上
- 使用
WorkItem.SyncToLatest()
将工作项重新同步到最新版本
- 重新应用在步骤 3 中被识别为脏的
Field
个值。
- 再次尝试保存
我有理由相信这是可行的,但我想知道是否有任何遗漏,或者是否有更好的 TFS 本机解决方案 API?
(抱歉没有代码,我可以在桌面上更新并提供示例)
我采用了我在原始问题中概述的实施方式,它似乎运行良好。这是重试逻辑的示例实现,它是从 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);
}
我有一个 TFS ISubscriber
实现可以修改 WorkItemChangedEvent
上的工作项。由于与 TFS 构建将工作项与构建相关联的争用,我们有时会收到 ItemAlreadyUpdatedOnServerException
。
虽然事件处理程序更新了几个工作项字段,但冲突仅发生在更新历史字段时。我们正在使用 WorkItem.Save(SaveFlags.MergeAll)
来保存工作项。
我想尝试在此特定情况下重试工作项更新。花了相当多的时间思考这个问题并研究了 API 中的可能性,我能想到的最好的办法是:
- 致电
WorkItem.Save(SaveFlags.MergeAll)
- 捕获
ItemAlreadyUpdatedOnServerException
然后在 catch 块中 - 查询并存储所有
Fields
IsDirty
而不是IsComputed
在保存失败的工作项上 - 使用
WorkItem.SyncToLatest()
将工作项重新同步到最新版本
- 重新应用在步骤 3 中被识别为脏的
Field
个值。 - 再次尝试保存
我有理由相信这是可行的,但我想知道是否有任何遗漏,或者是否有更好的 TFS 本机解决方案 API?
(抱歉没有代码,我可以在桌面上更新并提供示例)
我采用了我在原始问题中概述的实施方式,它似乎运行良好。这是重试逻辑的示例实现,它是从 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);
}