Вопрос
Я ищу способ получить параллельную коллекцию на С# или, по крайней мере, коллекцию, поддерживающую параллельный перечислитель.Прямо сейчас я получаю исключение 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 их (отличной) документации.