3

在我的算法中,我試圖做的是以下。c#並行For循環索引異常刪除元素後

while (R.Count > 0) 
{ 
    //R is also List<string>() 
    var N = new List<string>(); 
    var first = R[0]; 
    N.Add(first); 
    R.Remove(first); 
    //below commented code runs just fine but it takes a lot of time that is why i need to do multithreading to make it faster 
    //for (int i = R.Count - 1; i >= 0; i--) 
    //{ 
    // if (hamming(first, R[i])) 
    // { //hamming is a function just compare two strings and returns true or false. 
    //  N.Add(R[i]); 
    //  R.RemoveAt(i); 
    // } 
    //} 

    //Below is code of my attempt of multithreading the loop. I have tried it with foreach loop as well and it gives same error 'index out of range or argument exception' 

    //ATTEMPT 1 :- 
    Parallel.For(0,R.Count, i => 
    { 

     if (hamming(first, R[i])) 
     { 
      N.Add(R[i]); 
      R.RemoveAt(i); 
     } 
    }); 
    //ATTEMPT 2 :- 
    Parallel.For(0,R.Count, i => 
    { 

     if (hamming(first, R[i])) 
     { 
      N.Add(R[i]); 
      R[i]=""; 
     } 
    }); 
    var K = R.Where(a => a == "").ToList(); 
    var nc = cou - N.Count; 
    //the value of 'K.Count' and 'nc' should be same here but I have checked in debugger its not the same. 

    N_Total.Add(N);//this is just a List<List<string>> 

}

的代碼是相當自我解釋,但我還是會嘗試進一步此詳述IR。

基本上我需要運行這個算法並比較代碼中顯示的值,如果漢明返回true,我必須將該值添加到'N'並將其從'R'中刪除,我必須將其刪除,因爲當下一個time while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while while run while'

如果有人需要了解更多,我可以進一步闡述。

我想要的是以某種多線程方式實現此目標,並且無例外地index out of rangeArgument exceptions

非常感謝。

回答

1

R使用Parallel.Foreach。 Parallel.Foreach會將您的列表拆分爲更小的塊並開始處理它們。所以來自不同線程的索引不會相互衝突。

對於N您將使用ConcurrentBag而不是List,因爲它的線程安全。這意味着當兩個線程發生添加項目到你的包時,奇怪的事情不會發生。

如果你刪除內部的項目,你應該通知所有線程從新的變化,這將是很難(和相當醜陋)實現。

List<string> R = new List<string>(); 


while (R.Count > 0) 
{ 
    var removing = new ConcurrentBag<long>(); 

    var N = new ConcurrentBag<string>(); 
    var first = R[0]; 
    N.Add(first); 
    R.Remove(first); 

    Parallel.ForEach(R, (item, state, index) => 
    { 
     if(hamming(first, item)) 
     { 
      N.Add(item); 

      R[(int)index] = null; // mark as null and ignore. 
            // this is not thread safe for versioning of list but doesn't matter. 
            // for R ConcurrentBag can be used too but it doesn't change results after all. 
     } 
    }); 

    // now we are safe to reorganize our collection. 
    R = R.Where(str => str != null).ToList(); // parallel execution doesn't help. see comments below. 
               // for very large collection this will finish in few milliseconds. 

    // get other stuff... 
} 
+0

ConcurrentBag'N'沒有任何擴展方法的'添加',我怎麼能添加項目呢? – touseef

+0

仔細檢查你的代碼。你是否在代碼的頂部放置了'使用System.Collections.Concurrent;'? @touseef –

+0

ConcurentBag有方法Add,https://msdn.microsoft.com/en-us/library/dd381779.aspx – MadOX

2

首先List<string>不是ThreadSafe這意味着它不應該用於並行操作。

試試看:ConcurrentBag<string>

ConcurentBag存在於System.Collections.Concurrent命名空間,其中包含幾個線程安全集合。


的另一件事是:

你要確保如果指數用它做任何事情之前存在。


ConcurentBag可能有一些限制,也許這是值得檢查從命名空間的集合:System.Collections.Concurrent那些是ThreadSafe

https://msdn.microsoft.com/en-us/library/system.collections.concurrent.aspx

+0

我試圖併發隊列,但它只能從begining(如果符合)對我來說THT不起作用刪除的項目,因爲我在並行,所以我不得不刪除這是循環當時訪問任何隨機項。 – touseef

+0

如何從中刪除項目?在你的情況下,你想使用'TryTake'方法,我假設返回(將其添加到另一個集合)並從源集合中刪除對象。 – MadOX