TFS 2010: WorkItem.Save triggers WorkItemChangedEvent again

Go To StackoverFlow.com

0

I better start off by explaining a high level overview of what I'm trying to do (just in case I'm going about this horribly wrong): In TFS, we have a "Story" workitem that includes a "priority" field. At any given time we have maybe 20-30 stories that have a priority. As an example, we might have 20 perfectly prioritized stories (1 through 20), and then want to create a new story that should be our new top priority. So, I want to be able to give it a priority of 1, and then have a server-side plugin that will update the priority on all of the other stories so that I end up with 1 through 21 (1 being the new story we just created).

To this end, I've created a server-side plugin for TFS 2010 that subscribes to WorkItemChangedEvent. It's smart enough to figure out if the priority was updated, so it only changes workitems in this case. The problem I run into is that if I alter the priority and run WorkItem.Save(), it triggers WorkItemChangedEvent again, and the priority has changed, so the logic is true, and it updates and saves again.

Earlier, I had created a server-side plugin that updated the time on one of the datetime fields to 00:00:00 (in the case that it wasn't already 00:00:00) and noticed this behavior. It wasn't TOO big of a problem, because on the second run through, nothing would happen because the time would already be 00:00:00. But in this case of trying to update the priorities on a whole bunch of work items, it's a deal-breaker. Is there a way to stop WorkItem.Save() from triggering a WorkItemChangedEvent? Maybe another way to go about doing this altogether?

2012-04-03 23:10
by ctb


0

Easiest way I know would solve this is to add a specific comment and then to to check the comment/history item of the work item to see that you last updated it as part of the change you're doing.

Also, check out the following post for pointers on how to create your service so that it remains stable.

2012-04-04 19:16
by jessehouwing
I'll mark this as an answer if nobody comes up with a better solution. It will work, but it's too bad if there's not a cleaner way - ctb 2012-04-05 15:14
sure i hope for a better solution as well. maybe you can find something in the sources of the tfs aggregator http://tfsaggregator.codeplex.com - jessehouwing 2012-04-05 19:04
I ended up going this route in the interest of time. I had to do one save where I updated the priority field as well as a boolean field, then the handler can ignore any case where the boolean is true. Then I did a second save where I set the boolean back to false. In that case the priority hasn't changed so, again, nothing happens - ctb 2012-04-09 15:49
Was afraid it would be the only answer. It's how Microsoft also uses the _NOCI_ on builds to prevent triggering another automated build after commit - jessehouwing 2012-04-10 13:33


0

I solved this issue in my own extension by checking if the changer identity is the service identity. If it is then the logic is skipped.

This seems like a slightly more elegant solution then tagging the data.

var workItemChangedArgs = notificationEventArgs as WorkItemChangedEvent;
var identityService = requestContext.GetService<IdentityService>();
var changerIdentity = identityService.ReadIdentities(
    requestContext,
    new List<IdentityDescriptor> {
        IdentityHelper.CreateDescriptorFromSid(workItemChangedArgs.ChangerSid)
    },
    QueryMembership.Expanded,
    null).Single();
if (!IdentityHelper.IsServiceIdentity(requestContext, changerIdentity)) {
    // Do stuff….
}
2014-07-17 13:56
by Tamir Daniely
Yeah, this sounds like a better idea. Frankly, I'm having a hard time believing that I didn't consider it (this was a long time ago and my memory is fuzzy), I wonder if I ran into some sort of problem or gotcha... I'll have to revisit the code and see if I can refactor it as you describe - ctb 2014-07-27 05:21