簡體   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