[英]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;
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 => { ... });
}
簡單得多。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.