【问题标题】:Using ConcurrentBag correctly正确使用 ConcurrentBag
【发布时间】:2015-11-18 16:31:27
【问题描述】:

编辑:谢谢,你让我意识到下面的代码不像我想象的那样工作,因为不知何故我认为 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;

【问题讨论】:

  • 这将从包中取出一件物品,然后返回,如果有物品的话。您可能希望循环并将您从包中获取的任何内容分配给局部变量。
  • 看起来您正在尝试实现队列队列,如果是这样,ConcurrentQueue 可能是更合适的数据结构。有什么理由需要嵌套结构而不是所有工作的简单扁平队列?
  • @Ian 是的,我需要优先级。 ConcurrentBag 0 的元素必须在 ConcurrentBag 1 的元素之前处理
  • @aevitas,我不关心回报,我需要 Count 减少到 0。PS:对不起,我误解了 cbag 的工作原理,可能不好

标签: c# multithreading concurrency


【解决方案1】:
  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 => { ... });
}

简单得多。

【讨论】:

  • 1) 据我了解,只有当密钥不存在时它才会失败(这不是我的情况)2)这是 TryTake 的工作方式。它也让我感到困惑,但它需要带有 out 参数的密钥。结果实际上必须与输入对象相同。 msdn.microsoft.com/en-us/library/dd287184(v=vs.110).aspx 3) 我会检查一下,谢谢 4) 我使用的 .Net 版本不支持 Parallel
  • 什么键? CBag 没有键控。 Take 没有输入。 out 的意思是“不能读,只能写”。关于 4,也许使用等效的东西或使用一些库。比管理所有这些集合要尴尬得多。
  • 哦!谢谢那是缺少的部分!现在我明白了,代码完全错误
猜你喜欢
  • 2013-03-09
  • 2014-09-09
  • 1970-01-01
  • 2023-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-02
  • 2013-12-27
相关资源
最近更新 更多