2010-04-07 13 views
9

Ho un metodo particolare che è a volte arrestandosi con un ArgumentException:LISTA <> AddRange gettando ArgumentException

Destination array was not long enough. Check destIndex and length, and the array's lower bounds.: 
at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable) 
at System.Collections.Generic.List`1.CopyTo(T[] array, Int32 arrayIndex) 
at System.Collections.Generic.List`1.InsertRange(Int32 index, IEnumerable`1 collection) 
at System.Collections.Generic.List`1.AddRange(IEnumerable`1 collection) 

Il codice che causa questo incidente simile a questa:

List<MyType> objects = new List<MyType>(100); 
objects = FindObjects(someParam); 
objects.AddRange(FindObjects(someOtherParam); 

Secondo MSDN, lista <> .AddRange() dovrebbe ridimensionarsi automaticamente secondo le necessità:

Se il nuovo conteggio (il conteggio corrente più la dimensione della raccolta) sarà maggiore di Capacità, la capacità dell'elenco < (di < (T>)>) viene aumentata automaticamente riallocando l'array interno per accogliere i nuovi elementi e gli elementi esistenti vengono copiati nel nuovo array prima che i nuovi elementi vengano aggiunti.

Qualcuno può pensare a una circostanza in cui AddRange potrebbe lanciare questo tipo di eccezione?


Edit:

In risposta alle domande sulle FindObjects (metodo). Praticamente è qualcosa del genere:

List<MyObject> retObjs = new List<MyObject>(); 

foreach(MyObject obj in objectList) 
{ 
    if(someCondition) 
     retObj.Add(obj); 
} 
+1

Cosa restituisce 'FindObjects'? Inoltre, perché inizializzate 'oggetti? Quindi riassegnateli subito alla riga successiva? –

+0

Quando aggiungi un elemento, controlla se la dimensione è abbastanza grande, altrimenti ridimensiona l'array interno che usa. Tuttavia, quando si utilizzano più thread, è possibile controllare, ottenere un falso e ridimensionare l'array, il thread successivo legge che c'è spazio sufficiente e non viene ridimensionato, quindi entrambi raggiungono l'effettivo 'this._items [this._size ++] = item ; 'codice allo stesso tempo ... facendo scoppiare il secondo thread. Quando Jon dice 'Lista ' non è thread-safe nella risposta qui sotto, questa è una delle cose 'Elenco ' non gestisce. –

+0

Non ho scritto il codice, sto semplicemente facendo il debug del problema. Ci sono molte cose strane che i manutentori trovano quando rovistano :) – Tim

risposta

20

Si sta tentando di aggiornare la stessa lista da più thread? Ciò potrebbe causare problemi ... List<T> non è sicuro per più scrittori.

+0

Il metodo FindObjects() crea istantaneamente un nuovo oggetto List <>, lo popola e lo restituisce. Sono tutti a thread singolo, quindi non credo ci siano possibilità che più thread funzionino sulla List. – Tim

+0

@Tim: Quindi non riesco a capire perché potrebbe accadere. Vedi se riesci a trovare un programma breve ma completo che mostri il problema. Se riusciamo a riprodurlo, dovremmo essere in grado di risolverlo. –

+0

Questo è più o meno quello che speravo di sentire. Non sono stato in grado di riprodurre questo problema e mi sembra che non dovrebbe mai accadere. Volevo solo assicurarmi che non mi mancasse qualcosa prima di rifiutarlo completamente come un problema. – Tim

0

Onestamente, non ne sono sicuro, ma perché non rimuovere semplicemente la dichiarazione della dimensione sull'inizializzazione della lista?

List`<MyType>` list = new List`<MyType>` 
+3

Poiché l'inizializzazione viene prontamente scartata. Non ha nemmeno * bisogno * di essere inizializzato in questo modo. –

Problemi correlati