ArgumentException при вызове .ToArray()

У меня есть список, который время от времени очищается. Код точно такой:

VisitorAgent[] toPersist;
List<VisitorAgent> v = (List<VisitorAgent>)state;

lock (v)
{
   toPersist = v.ToArray();                       

   v.Clear();
}

//further processing of toPersist objects

Сегодня я только что получил исключение Argument, которое не имеет для меня смысла, если только не было проблемы с памятью. Но если это так, то почему не исключение OOM? Что может вызвать это исключение при вызове ToArray()?

System.ArgumentException: Destination array was not long enough. Check destIndex and 
length, and the array's lower bounds.

Я использую .NET 3.5 и С#.


person Mike_G    schedule 06.07.2010    source источник


Ответы (2)


Это просто кричит о состоянии гонки (оператор lock был первой подсказкой).

Я предполагаю, что какой-то другой код (в другом потоке) был добавлен к List<T> после того, как он выделил целевой массив, но до того, как он успел его скопировать.

Первое, что я бы сделал, это перепроверил, что каждый возможный доступ к вашему списку состояний правильно заключен в оператор lock.

person Ben M    schedule 06.07.2010
comment
Я почти уверен, что вы правы, после того, как вы это сказали, я просмотрел все свои ссылки на объект состояния, и похоже, что я пропустил одну. - person Mike_G; 06.07.2010

Что-то меняет список state между временем выделения массива и временем копирования содержимого списка. Блокировка v не повлияет на это, если код, который заполняет состояние, не знает о v (чего в этом примере, похоже, нет).

person Ben Hoffstein    schedule 06.07.2010