3

В моем алгоритме я пытаюсь сделать следующее.C# Параллельный для исключения индекса цикла после удаления элемента

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

}

Кодекс говорит само за себя, но я все еще будет пытаться разработать ИК дальше здесь.

В принципе, мне нужно запустить этот алгоритм и сравнить значения, как показано в коде, и если hamming возвращает true, я должен добавить это значение в 'N' и удалить его из 'R', я должен удалить его, потому что, когда следующий время, в течение которого выполняется цикл while во время цикла. «R» должен быть меньше, и только те значения должны присутствовать в R, которые не удовлетворяли условию хамминга в предыдущем цикле цикла.

Я могу уточнить, если кто-то должен понять больше.

То, что я хочу, что для достижения этой цели в некоторых многопоточных образом и без исключений index out of range или Argument exceptions.

Большое спасибо.

ответ

1

Использование Parallel.Foreach на R. Parallel.Foreach разделит ваш список на более мелкие куски и начнет их обрабатывать. поэтому индексы из разных потоков не будут сталкиваться друг с другом.

для N вы будете использовать ConcurrentBag вместо List, потому что его нить безопасна. это означает, что, когда два потока, случается, добавляют элемент в сумку, странные вещи не произойдут.

Если вы удаляете элементы внутри Parallel, вы должны предупредить все темы из новых изменений, которые будут сложными (и довольно уродливыми) для реализации.

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

проверьте свой код. вы положили 'using 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

Я попытался Параллельная очередь, но она только удаляет элементы из главной страницы (если согласованные), так THT не работаем для меня, потому что я параллельно, так что я должен удалить любой случайный элемент, который, что цикл с доступом в то время. – touseef

+0

как вы удаляете элементы из него?В вашем случае вы хотите использовать метод TryTake, я предполагаю, что возвращает (добавить его в другую коллекцию) и удалить объект из исходной коллекции. – MadOX