Вопрос по list, c#, multithreading – Изменение списка из другого потока во время итерации (C #)

8

Error: User Rate Limit Exceeded

foreach (Type name in aList) {
   name.doSomething();
}

Error: User Rate Limit Exceeded

aList.Remove(Element);

Во время выполнения это вызывает исключение InvalidOperationException: коллекция была изменена; Операция перечисления может не выполняться. Каков наилучший способ справиться с этим (я бы предпочел, чтобы это было довольно просто, даже за счет производительности)?

Спасибо!

Ваш Ответ

6   ответов
0

BlockingCollection<T>GetConsumingEnumerable()

void SomeMethod()
{
    BlockingCollection<int> col = new BlockingCollection<int>();

    Task.StartNew( () => { 

        for (int j = 0; j < 50; j++)
        {
            col.Add(j);
        }

        col.CompleteAdding(); 

     });

    foreach (var item in col.GetConsumingEnumerable())
    {
       //item is removed from the collection here, do something
       Console.WriteLine(item);
    }
}
9

Method #1:

Error: User Rate Limit Exceeded

// Writer
lock (aList)
{
  aList.Remove(item);
}

// Reader
lock (aList)
{
  foreach (T name in aList)
  {
    name.doSomething();
  }
}

Method #2:

Error: User Rate Limit ExceededforeachError: User Rate Limit Exceeded

// Writer
lock (aList)
{
  aList.Remove(item);
}

// Reader
List<T> copy;
lock (aList)
{
  copy = new List<T>(aList);
}
foreach (T name in copy)
{
  name.doSomething();
}

Method #3:

Error: User Rate Limit ExceededlockError: User Rate Limit ExceededaListError: User Rate Limit Exceededvolatile.

// Variable declaration
object lockref = new object();
volatile List<T> aList = new List<T>();

// Writer
lock (lockref)
{
  var copy = new List<T>(aList);
  copy.Remove(item);
  aList = copy;
}

// Reader
List<T> local = aList;
foreach (T name in local)
{
  name.doSomething();
}
Я должен также указать, пока я думаю об этом, что № 3 необходимо соблюдатьexactly как представлено. Любое отклонение (например, решение о том, что назначениеlocalError: User Rate Limit Exceeded
Error: User Rate Limit ExceededaListError: User Rate Limit Exceeded
Error: User Rate Limit ExceededaListError: User Rate Limit Exceededlock(this)Error: User Rate Limit Exceeded
10

What is the best way to handle this (I would perfer it to be rather simple even at the cost of performance)?

Error: User Rate Limit ExceededRemoveError: User Rate Limit Exceeded

EitherError: User Rate Limit ExceededConcurrentBag orError: User Rate Limit ExceededanythingError: User Rate Limit Exceeded

Error: User Rate Limit Exceeded Henrik Karlsson
1

Error: User Rate Limit Exceededmore than oneError: User Rate Limit ExceededError: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

8

Error: User Rate Limit Exceeded

lock (aList) {
  foreach (Type name in aList) {
     name.doSomething();
  }
}

Error: User Rate Limit Exceeded

lock (aList) {
  aList.Remove(Element);
}

Error: User Rate Limit Exceeded

Error: User Rate Limit Exceeded Henrik Karlsson
0

Error: User Rate Limit Exceeded

foreach (Type name in aList.ToArray()) 
{ name.doSomething(); }

Error: User Rate Limit Exceeded

Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededToArrayError: User Rate Limit ExceededRemove может привести к гонке, что может привести к другому виду исключения. Это хорошая мысль, хотя! Обратитесь к моемуanswer чтобы увидеть, как заставить это работать правильно.

Похожие вопросы