正确使用 ConcurrentBag
本文关键字:ConcurrentBag | 更新日期: 2023-09-27 18:22:30
编辑:谢谢,你让我意识到下面的代码没有像我假设的那样工作,因为不知何故我认为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;
-
stepToDo.TryTake(out obj);
可能会失败,你不会处理它。 - 你为什么要
out
引用方法参数?这只会覆盖参数。如果你把它扔掉,为什么要争论呢?更有可能的是,这是某种误解。 -
can I assume it will enter here once per ConcurrentBag
由于对包的访问显然是并发的,因此多个访问线程可能会看到0
。所以是的,你需要更好地处理这种情况。
也许,您不应该让事情变得如此困难,并将lock
与非并发数据结构结合使用。只有当袋子操作的频率很高时,这才是一个好主意,这似乎不太可能。
这个呢:
foreach (/*processing step*/) {
Parallel.ForEach(/*item in the step*/, x => { ... });
}
简单得多。