Hace

 foreach(T value in new List<T>(oldList) )

es peligroso (y cara) cuando oldList contiene 1 millones de objeto T ?

Más general ¿cuál es la mejor manera de enumerar más de oldList dado que los elementos se añaden/quitan durante la enumeración…

Me parece que hay dos diferentes preguntas aquí. No estoy seguro de por qué han sido combinados.

OriginalEl autor Toto | 2011-02-15

10 Comentarios

  1. 7

    La regla general es, usted no debe modificar la misma colección en la que usted está enumerando. Si quieres hacer algo como eso, mantener otra colección que va a seguir la pista de que elementos agregar/eliminar de la colección original y, a continuación, después de salir del bucle, realizar el agregar/quitar operación en la colección original.

    Ok, pero en realidad es un hilo de otro que puede modificar la colección. Por alguna razón, no puedo sincronizar la iteración vs la adición/extracción.
    Como lo mencioné en mi respuesta actualizada, si usted está utilizando .NET 4.0, considere el uso Concurrente de las Colecciones.

    OriginalEl autor Sachin Shanbhag

  2. 4

    Por lo general basta con crear una lista de todos los objetos a ser quitado o añadido.

    Dentro de la foreach acabo de añadir elementos a la colección adecuada y modificar el original de la colección después de la foreach han completado (bucle a través de la removeItems y addItems colección)

    OriginalEl autor Dirk Trilsbeek

  3. 4

    al igual que este

    var itemsToBeRemoved = new List<T>();
    
    foreach (T item in myHugeList) 
    {
        if (/*<condition>*/)
             itemsToBeRemoved.Add(item);
    }
    
    myHugeList.RemoveRange(itemsToBeRemoved);

    OriginalEl autor MacX

  4. 1

    Si usted significa que usted puede agregar o quitar objetos de otro hilo, me gustaría:
    1-sincronizar los hilos
    2 – en el agregar o quitar hilos, crear una lista de elementos que se agregan o eliminan
    3 – y, a continuación, eliminar estos elementos en una sección crítica (por lo que es pequeño, no tiene sincronizar mientras que la adición de elementos a la lista de eliminación)

    Si usted no quiere hacer eso, se puede utilizar en lugar de un foreach, que evitaría la excepción, pero que habría que tener mucho cuidado de manera que no tenga otro tipo de excepciones

    Por alguna razón, no puedo sincronizar la iteración vs la adición/extracción.El de la iteración es sin duda la solución a mi problema.
    Estoy feliz de ayudar. Si fue la solución para su problema, por favor podría marcar como respuesta, haga clic en la «verificación verde signo de»? 🙂 gracias!

    OriginalEl autor JSBach

  5. 1

    Si usted está usando un bucle Foreach para la modificación de la colección, a continuación, obtendrá este error como el siguiente.

    List<string> li = new List<string>();
        li.Add("bhanu");
        li.Add("test");
    
        foreach (string s in li)
        {
            li.Remove(s);
        }

    Solución de uso del Bucle For de la siguiente manera.

    for (int i = 0; i < li.Count; i++)
        {
            li.RemoveAt(i);
            i--;
        }

    OriginalEl autor Bhanu pratap

  6. 0

    Usted puede recorrer a través de la lista sin necesidad de utilizar un enumerador, para hacer algo como…

    for(int i = 0;i<oldList.Count;i++) {
       var value = oldList[i];
    
       ...
    
       if(itemRemoveCondition) {
         oldList.RemoveAt(i--);
       }
    }
    Me parece que un poco confuso, ¿por qué no simplemente bucle hacia atrás en la lista? Entonces usted no necesita mezclar el incremento y decremento del índice.
    Yo bucle hacia atrás de un problema con la adición de elementos.
    ¿El fin de la condición del bucle se evalúa en cada iteratin o solo una vez ?
    La condición final será evaluado en cada iteración.
    cierto, se me pasó la adición de una parte de la cuestión.

    OriginalEl autor Nick Jones

  7. 0

    Para mí, lo primero que debe considerar el uso de algún tipo de paginación de datos, porque tener de 1 millón de artículos-gran lista podría ser peligroso en sí.

    Has oído hablar de modelo de Unidad de Trabajo?

    Puede implementar para marcar objetos para crear, actualizar o borrar, y más tarde, la llamada «SaveChanges», «Confirmar» o cualquier otro haciendo el trabajo de «aplicar cambios», y que voy a hacer.

    Por ejemplo, se itera sobre la enumerable (oldList) y marca como «eliminar». Más tarde, la llamada «SaveChanges» y la más abstracta, genérica unidad de trabajo iterar sobre el pequeño, filtra la lista de objetos para trabajar con.

    De todos modos, evitar las listas de un millón de artículos. Usted debe trabajar con paginado listas de objetos.

    OriginalEl autor Matías Fidemraizer

  8. 0

    Será «lenta», pero no hay mucho más que usted puede hacer al respecto, excepto que se ejecuta en un subproceso en segundo plano. E. g. el uso de un BackgroundWorker.

    Si sus operaciones en la lista sólo se producen en un hilo, el enfoque correcto es agregar los elementos a agregar/quitar para separar las listas, y realizar esas operaciones después de su iteraciones ha terminado.

    Si usted hacer uso de múltiples hilos usted tendrá que buscar en la programación multiproceso, y por ejemplo, el uso cerraduras o probablemente mejor un ReaderWriterLock.

    ACTUALIZACIÓN:
    Como se mencionó en otro Desbordamiento de pila pregunta, esto es ahora posible sin el esfuerzo .NET 4.0 cuando el uso de las colecciones simultáneas.

    OriginalEl autor Steven Jeuris

  9. 0

    foreach(valor de T en la nueva Lista(oldList).ToList() ) – darle una oportunidad

    OriginalEl autor iq.psb

  10. 0

    puede utilizar un indicador del interruptor de la modificación temporal de la lista, mientras que el original es enumerado.

    ///donde está enumerando

    isBeingEnumerated = true
    foreach(T value in new List<T>(oldList) )
    isBeingEnumerated = false
    SyncList(oldList with temporaryList)

    ///donde está modificando al enumerar

    if isBeingEnumerated then
    use a temporaryList to make the changes.

    OriginalEl autor Vijay Babu

Dejar respuesta

Please enter your comment!
Please enter your name here