繁体   English   中英

正确使用ConcurrentBag

[英]Using ConcurrentBag correctly

编辑:谢谢,您让我意识到下面的代码无法正常运行,因为我以某种方式认为cbag像哈希集一样工作。 抱歉,您为我省了很多麻烦:)

以下函数是唯一可以更改_currentSetOfStepsProcessing的函数。 可以从不同的线程调用此函数。 我不确定我是否正确理解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;
  1. stepToDo.TryTake(out obj); 可能会失败,您将无法处理。
  2. 为什么要out引用方法参数? 这只会覆盖参数。 如果把它丢掉,为什么还要争论呢? 这很可能是某种误解。
  3. can I assume it will enter here once per ConcurrentBag因为对包的访问显然是并发的,多个访问线程可能会看到0 所以是的,您需要更好地处理这种情况。

可能,您不应使事情变得如此困难,而应将lock与非并发数据结构结合使用。 只有在似乎不太可能进行频繁的制袋操作时,这才是一个好主意。

那这个呢:

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

简单得多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM