将后台工作人员的数量限制为两个,并在添加时完成工作

Limit number of backgroundworkers to two and complete jobs as they are added

我目前有一个 treeview,其中 treeView 项目绑定到一个 ICommand 接口,当项目选择更改如下时调用该接口:

private ICommand _TreeviewSelectedItemChanged;
        public ICommand TreeviewSelectedItemChanged
        {
            get
            {
                if (_TreeviewSelectedItemChanged == null)
                {                    
                    _TreeviewSelectedItemChanged = new DelegateCommand(delegate()
                    {
                        foreach (TreeViewClass tree in treeViewObsCollection)
                        {
                            TreeViewSubItem subItem = tree.mainNodes.FirstOrDefault(s => s.treeViewItemIsSelected);
                            if (subItem != null)
                            {
                                queueofJobs.Enqueue(subItem.subItemName);                                
                                //Call Background Worker here?
                            }                            
                        } 
                    });
                }
                return _TreeviewSelectedItemChanged;
            }
        }

用户点击的每个 treeView 项目都将添加到这个名为 queueofJobs 的队列中。我想做的是这样的:

  1. 第一次向队列中添加项目时,后台工作程序将自动启动以处理与该项目相关的耗时任务。我在这里面临的挑战是,队列可能会根据用户在树视图项目上单击的项目数量而改变。

  2. 后台工作者在任何时候都应限制为最多 2 个活动,因为这些操作是 read/write 依赖的,并且启动太多会对文件系统性能产生负面影响。

  3. 后台工作人员将执行添加到队列中的所有作业(一次 2 个作业),直到队列变空。

我很好地实现了一个后台工作者,但我目前在尝试实现上述场景时遇到困难,即作业队列根据用户选择的项目而变化,并且 2 个后台工作者正在执行队列中的这些作业,直到队列中变空了。

如果有人能帮助我指出适合我的问题的方法,那就太好了。任何其他方法而不是 backgroundworker 也可以。提前致谢。

BackgroundWorker 不再是 right/best 工具。您可以为此使用 TPL Dataflow's ActionBlock<T>

ActionBlock<TreeViewSubItem> workerBlock = 
    new ActionBlock<TreeViewSubItem>(i => DoWork(i),
        new ExecutionDataflowBlockOptions() { MaxDegreeOfParallelism = 2 });

然后只需调用:

if (subItem != null)
    workerBlock.Post(subItem);  

这将通过在单独的线程池线程中为每个项目调用 DoWork 来处理每个子项目(最多并行 2 个)。