Вопрос

Я ищу способ получить параллельную коллекцию на С# или, по крайней мере, коллекцию, поддерживающую параллельный перечислитель.Прямо сейчас я получаю исключение InvalidOperationException при изменении коллекции, над которой я выполняю итерацию.Я мог бы просто глубоко скопировать коллекцию и работать с частной копией, но мне интересно, есть ли лучший способ

Фрагмент кода:

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

--редактировать--

Я принял ответ, но также обнаружил, что мне нужно убедиться, что код, записывающий в коллекцию, также должен попытаться получить блокировку.

    private void addKillString(String s)
    {
        lock (killStrings)
        {
            killStrings.Add(s);
        }
    }
Это было полезно?

Решение

Помимо глубокого копирования, лучше всего заблокировать коллекцию:

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

Другие советы

Итак, я не совсем понимаю, о чем вы спрашиваете, но команда Parallel Extensions собрала кое-что, что может отвечать всем требованиям.См. этот пост в блоге, в частности, о перечисление параллельных коллекций.Он также содержит ссылку для загрузки Parallel CTP, и вы, конечно, можете просмотреть остальные сообщения в блоге, чтобы получить представление о том, для чего предназначена CTP и как работает модель программирования.

Если вы хотите использовать коллекции FCL, то блокировка — единственный способ поддержать итерацию/модификацию из нескольких потоков, которые могут перекрываться.

Однако будьте осторожны с тем, что вы используете в качестве объекта блокировки.Использование SyncRoot является хорошей идеей только в том случае, если сама коллекция является закрытым членом класса, который ее использует.Если коллекция защищена или общедоступна, клиент вашего класса может самостоятельно заблокировать ваш SyncRoot, что может привести к взаимоблокировке кода вашего класса.

Если вы хотите взглянуть на стороннюю библиотеку коллекций, я рекомендую отличную Библиотека общих коллекций C5.У них есть семейство древовидных коллекций, которые можно легко и безопасно изменять и повторять одновременно без блокировки — подробности см. в разделах 8.10 и 9.11 их (отличной) документации.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top