并行处理TFS-WorkItems

时间:2016-04-27 15:10:50

标签: c# tfs

我试图将大量12,000件的大量TFS-WorkItem批量插入到我自己的数据模型中。我读得非常简单:

        internal static async Task<IEnumerable<WorkItem>> GetAllWorkItemsAsync()
        {
            var allItems = await Task.Run(() =>
            {
                var result = _workItemStore.Query(@"SELECT * FROM WorkItems").Cast<WorkItem>().ToList();
                return result;
            });

            return allItems;
        }

然后我会以平行方式运行所有这些并映射到我自己的模型:

    internal async Task<IEnumerable<Model.WorkItem>> GetAllWorkItemsAsync()
    {
        var allWorkItems = await QueryHelper.GetAllWorkItemsAsync();

        var result = await Task.Factory.StartNew(() =>
        {
            var res = new List<Model.WorkItem>();

            Parallel.ForEach(allWorkItems, wi =>
            {
                var item = new Model.WorkItem();
                _mapper.MapCoreData(wi, item);
                _mapper.MapCustomData(wi, item);
                _mapper.MapLinks(wi, item);

                res.Add(item);
            });
            return res;
        }, TaskCreationOptions.LongRunning);

        return result;
    }

我的问题:在我尝试访问工作项字段时,请尽快通过:

    internal void MapCustomData(WorkItem source, Model.WorkItem target)
    {
        var sponsor = source.Fields["Sponsor"]?.Value.ToString();
        var requirementType = source.Fields["Requirement Type"]?.Value.ToString();

        target.WorkItemCustomData = new Model.WorkItemCustomData
        {
            Sponsor = sponsor,
            RequirementType = requirementType,
            WorkItemId = target.Id
        };
    }

我得到以下例外:

  

类型&#39; System.InvalidOperationException&#39;的例外情况发生在   mscorlib.dll但未在用户代码中处理

     

其他信息:收集已修改;枚举操作   可能无法执行。

有趣的是,我从不改变价值观,而只是阅读它们并填写我自己的模型。

TFS模型中是否有任何已知的机制,它有一些共享列表,或者我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

你期待发生什么?您正在使用线程中的线程不安全集合:

        var res = new List<Model.WorkItem>();

        Parallel.ForEach(allWorkItems, wi =>
        {
            var item = new Model.WorkItem();
            _mapper.MapCoreData(wi, item);
            _mapper.MapCustomData(wi, item);
            _mapper.MapLinks(wi, item);

            res.Add(item);
        });
        return res;

要么锁定访问集合以提供线程安全性,要么使用固有的线程安全集合,如ConcurrentBag