2016-08-16 48 views
0

我的問題是類似Parallel Foreach Race Condition並行的foreach計數

了很多,但它並沒有回答非常明確,它在這個意義上,我需要計算該物體在不同的換每個滿足一定的條件。如果它確實需要將它添加到列表中。

所以像這樣

List<int> MetCriteria = new List<int>(); 
Parallel.ForEach(dt.AsEnumerable(), (entry,state) => { 

    if (Convert.ToInt32(entry["Time"]) > 100)//in miliseconds 
    MetCriteria.add(Convert.ToInt32(entry["EntryID"]); 
}); 

所以,很顯然這個名單不包含像線程鎖或東西,一個正常的,每個會,因爲我需要一些方法來保持MetCriteria對象同步的所有值,但我不確定如何做到這一點

任何幫助,請

+0

「if」語句是字面意思,你正在嘗試做什麼?如果是這樣,你爲什麼使用並行處理? – Enigmativity

+0

我必須根據金額做不同的事情,所以如果它超過100,它會符合條件,如果沒有,則需要檢查其他變量,並將其添加到單獨的列表中。那麼我必須針對每個條目調用Web服務,根據輸入時間可能需要一些時間 – Neil

+0

您是否簡單地比較了像Convert.ToInt32(entry [「Time」])> 100'這樣的值並添加了項目列表,然後調用Web服務?還是你在'if'裏面調用一個web服務? – Enigmativity

回答

1

可以使用線程安全的集合像ConcurrentBag

var MetCriteria = new ConcurrentBag<int>(); 
Parallel.ForEach(dt.AsEnumerable(), (entry,state) => { 

    if (Convert.ToInt32(entry["Time"]) > 100)//in miliseconds 
    MetCriteria.add(Convert.ToInt32(entry["EntryID"]); 
}); 
1

確定您可以鎖定您的列表以使其威脅安全。但我會使用像Dovydas Sopa建議的線程安全集合。

List<int> MetCriteria = new List<int>(); 
Parallel.ForEach(dt.AsEnumerable(), (entry, state) => 
{ 
    if (Convert.ToInt32(entry["Time"]) > 100)//in miliseconds 
    { 
     lock (MetCriteria) 
     { 
      MetCriteria.Add(Convert.ToInt32(entry["EntryID"])); 
     } 

    } 
}); 
+0

哪一個會更資源友好。這個答案或Dovydas Sopa的 – Neil

+0

如果我要使用你的答案,並且我有一個if語句在這個鎖的外面,比如'if(MetCriteria.count> 1000)'它不應該影響它的正確性(它只是讀取數據,不會改變) ? – Neil

+2

接受Dovydas Sopa的回答,這是應該如何完成的。鎖只是防止來自不同線程的同時訪問,並使_thread safe_。從技術上講,對象被鎖定,另一個訪問線程必須等到上一個動作完成 – fubo