Pergunta

Estou procurando uma maneira de obter uma coleção simultânea em C# ou pelo menos uma coleção que suporte um enumerador simultâneo.No momento, estou recebendo uma InvalidOperationException quando a coleção sobre a qual estou iterando muda.Eu poderia simplesmente copiar profundamente a coleção e trabalhar com uma cópia privada, mas estou me perguntando se talvez haja uma maneira melhor

Fragmento de código:

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

--editar--

Peguei a resposta, mas também descobri que precisava garantir que o código que estava gravando na coleção também precisasse tentar obter um bloqueio.

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

Solução

Além de fazer uma cópia profunda, sua melhor aposta seria bloquear a coleção:

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

Outras dicas

Portanto, não tenho certeza do que você está perguntando, mas a equipe do Parallel Extensions reuniu algumas coisas que podem ser adequadas.Veja esta postagem do blog em particular, sobre enumerando coleções paralelas.Ele também contém um link para baixar o CTP paralelo e, é claro, você pode navegar pelo restante das postagens do blog para ter uma ideia do que o CTP pretende fazer e como funciona o modelo de programação.

Se você quiser usar as coleções FCL, o bloqueio é a única maneira de oferecer suporte à iteração/modificação de vários threads que podem se sobrepor.

Porém, tenha cuidado com o que você usa como objeto de bloqueio.Usar SyncRoot só é uma boa ideia se a coleção em si for um membro privado da classe que a utiliza.Se a coleção for protegida ou pública, um cliente da sua classe poderá obter seu próprio bloqueio no SyncRoot, potencialmente travando com o código da sua classe.

Se você estiver interessado em dar uma olhada em uma biblioteca de coleções de terceiros, recomendo o excelente Biblioteca de coleções genéricas C5.Eles têm uma família de coleções baseadas em árvores que podem ser modificadas e iteradas de maneira fácil e segura ao mesmo tempo, sem bloqueio - consulte as seções 8.10 e 9.11 de sua (excelente) documentação para obter detalhes.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top