Reputation: 1085
Edit: Thank you, you made me realise that the code below is not working as I assumed, since somehow I thought that cbag works like a hashset. Sorry about it, you saved me some headache :)
the following function is the only function that can change _currentSetOfStepsProcessing. This function can be called from different threads. I am not sure if I understood correctly the use of a ConcurrentBag, so please let me know if in your opinion this can work. _stepsToDo datastructure is never modified once the process starts.
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;
Upvotes: 1
Views: 827
Reputation: 171178
stepToDo.TryTake(out obj);
might fail, you don't handle that.out
-referencing the method argument? This simply overwrites the argument. Why take an argument if you throw it away? More likely, this is a misunderstanding of some kind.can I assume it will enter here once per ConcurrentBag
since access to the bag is apparently concurrent multiple accessing threads might see 0
. So yes, you need to handle that case better.Probably, you should not make things so difficult and use lock
in combination with non-concurrent data structures. This would only be a good idea if there was a high frequency of bag operations which seems unlikely.
What about this:
foreach (/*processing step*/) {
Parallel.ForEach(/*item in the step*/, x => { ... });
}
Much simpler.
Upvotes: 1