Pregunta

Estoy buscando una manera de obtener una colección concurrente en C# o al menos una colección que admita un enumerador concurrente.En este momento recibo una InvalidOperationException cuando cambia la colección sobre la que estoy iterando.Podría simplemente copiar en profundidad la colección y trabajar con una copia privada, pero me pregunto si tal vez haya una manera mejor.

Fragmento de código:

foreach (String s in (List<String> )callingForm.Invoke(callingForm.delegateGetKillStrings))
    {
        //do some jazz
    }

--editar--

Tomé la respuesta, pero también descubrí que necesitaba asegurarme de que el código que estaba escribiendo en la colección también debía intentar obtener un bloqueo.

    private void addKillString(String s)
    {
        lock (killStrings)
        {
            killStrings.Add(s);
        }
    }
¿Fue útil?

Solución

Además de hacer una copia profunda, lo mejor que puedes hacer es bloquear la colección:

   List<string> theList = (List<String> )callingForm.Invoke(callingForm.delegateGetKillStrings);
    lock(theList.SyncRoot) {
        foreach(string s in theList) {
               // Do some Jazz
        }
    }

Otros consejos

Así que no estoy muy seguro de lo que estás preguntando, pero el equipo de Parallel Extensions ha reunido algunas cosas que podrían cumplir los requisitos.Vea esta publicación de blog en particular, sobre enumerando colecciones paralelas.También contiene un enlace para descargar el CTP paralelo y, por supuesto, puede navegar por el resto de las publicaciones del blog para tener una idea de lo que debe hacer el CTP y cómo funciona el modelo de programación.

Si desea utilizar las colecciones FCL, el bloqueo es la única forma de admitir la iteración/modificación de múltiples subprocesos que pueden superponerse.

Sin embargo, tenga cuidado con lo que utiliza como objeto de bloqueo.Usar SyncRoot sólo es una buena idea si la colección en sí es un miembro privado de la clase que la usa.Si la colección está protegida o es pública, entonces un cliente de su clase puede tomar su propio bloqueo en su SyncRoot, potencialmente interbloqueándose con el código de su clase.

Si está interesado en echar un vistazo a una biblioteca de colecciones de terceros, le recomiendo la excelente Biblioteca de colección genérica C5.Tienen una familia de colecciones basadas en árboles que se pueden modificar e iterar al mismo tiempo de manera fácil y segura sin bloquear; consulte las secciones 8.10 y 9.11 de su (excelente) documentación para obtener más detalles.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top