C# 正确使用ConcurrentBag

C# 正确使用ConcurrentBag,c#,multithreading,concurrency,C#,Multithreading,Concurrency,编辑:谢谢你,你让我意识到下面的代码并不像我想象的那样工作,因为不知何故我认为cbag就像一个哈希集一样工作。很抱歉,你帮我省了点麻烦:) 以下函数是唯一可以更改_currentSetOfSepsProcessing的函数。可以从不同的线程调用此函数。我不确定我是否正确理解ConcurrentBag的用法,因此请让我知道您认为这是否可行_一旦进程启动,stepsToDo数据结构就不会被修改 void OnStepDone(InitialiseNewUserBase obj) {

编辑:谢谢你,你让我意识到下面的代码并不像我想象的那样工作,因为不知何故我认为cbag就像一个哈希集一样工作。很抱歉,你帮我省了点麻烦:)

以下函数是唯一可以更改_currentSetOfSepsProcessing的函数。可以从不同的线程调用此函数。我不确定我是否正确理解ConcurrentBag的用法,因此请让我知道您认为这是否可行_一旦进程启动,stepsToDo数据结构就不会被修改

void OnStepDone(InitialiseNewUserBase obj)
    {
        var stepToDo = _stepsToDo[_currentSetOfStepsProcessing];

        stepToDo.TryTake(out obj);

        if (stepToDo.Count == 0) //can I assume it will enter here once per ConcurrentBag?
        {
            if (_currentSetOfStepsProcessing < _stepsToDo.Count - 1)
            {
                _currentSetOfStepsProcessing++;
            }
        }
    }

    List<ConcurrentBag<InitialiseNewUserBase>>      _stepsToDo = new List<ConcurrentBag<InitialiseNewUserBase>>();
    Action                                          _onFinish;
    int                                             _currentSetOfStepsProcessing;
void OnStepDone(InitialiseNewUserBase obj)
{
var stepToDo=_stepToDo[_currentSetOfSepsProcessing];
步骤Todo.TryTake(输出对象);
如果(stepToDo.Count==0)//我可以假设它将在这里为每个ConcurrentBag输入一次吗?
{
if(_currentSetOfSepsProcessing<_stepsToDo.Count-1)
{
_CurrentSetOfSepsProcessing++;
}
}
}
列表_stepsToDo=新列表();
动作完成;
int_currentSetOfSepsProcessing;
  • stepToDo.TryTake(out obj)可能会失败,您无法处理
  • 为什么
    out
    -引用方法参数?这只是覆盖了参数。如果你把争论扔掉了,为什么还要接受呢?更可能的是,这是某种误解
  • 我可以假设它将在这里为每个ConcurrentBag输入一次吗
    ,因为对bag的访问显然是并发的,多个访问线程可能会看到
    0
    。所以是的,你需要更好地处理这个案子
  • 也许,您不应该让事情变得如此困难,而应该将
    lock
    与非并发数据结构结合使用。只有在行李操作频率很高的情况下,这才是一个好主意,这似乎不太可能

    那么这个呢:

    foreach (/*processing step*/) {
     Parallel.ForEach(/*item in the step*/, x => { ... });
    }
    

    更简单。

    这将从袋子中取出一件物品,然后返回,如果有物品的话。您可能希望循环并将从包中获取的任何内容分配给局部变量。看起来您正在尝试实现队列队列,如果是这样,
    ConcurrentQueue
    可能是更合适的数据结构。你为什么需要嵌套结构而不是简单的工作队列?@Ian是的,我需要优先级。必须先处理ConcurrentBag 0的元素,然后再处理ConcurrentBag的元素1@aevitas,我不关心返回,我需要计数减少到0。注:抱歉,我误解了cbag的工作原理,may bad1)据我所知,只有在密钥不存在的情况下才会失败(这不是我的情况)2)这是TryTake的工作方式。它也让我感到困惑,但它想要带out参数的键。结果实际上必须与输入对象相同。3) 我会检查一下,谢谢4)我使用的是一个不支持ParallelKey的.Net版本?CBag没有键控。没有可接受的输入。out的意思是“不能读,只能写”。关于第四点,可以使用等效的东西或使用一些库。比管理所有这些收藏要轻松得多。哦!谢谢你,那是遗漏的部分!现在我明白了,代码完全错了