получение исключения аргумента в параллельном словаре при сортировке и отображении по мере его обновления
Мне трудно воспроизвести ошибку в следующей программе, в которой несколько потоков параллельно обновляют параллельный словарь, а основной поток отображает состояние словаря в отсортированном порядке через фиксированные промежутки времени, пока не завершатся все потоки обновления.
public void Function(IEnumerable<ICharacterReader> characterReaders, IOutputter outputter)
{
ConcurrentDictionary<string, int> wordFrequencies = new ConcurrentDictionary<string, int>();
Thread t = new Thread(() => UpdateWordFrequencies(characterReaders, wordFrequencies));
bool completed = false;
var q = from pair in wordFrequencies orderby pair.Value descending, pair.Key select new Tuple<string, int>(pair.Key, pair.Value);
t.Start();
Thread.Sleep(0);
while (!completed)
{
completed = t.Join(1);
outputter.WriteBatch(q);
}
}
Функция получает список символьных потоков и вывод. Функция поддерживает параллельный словарь частот слов слов, прочитанных из каждого из потоков символов (параллельно). Слова считываются новым потоком, и основной поток выводит текущее состояние словаря (в отсортированном порядке) каждые 1 миллисекунду, пока все входные потоки не будут прочитаны (на практике вывод будет примерно таким же, как каждые 10 секунд, но ошибка появляется только для очень маленьких значений). Функция WriteBatch просто пишет в консоль:
public void WriteBatch(IEnumerable<Tuple<string, int>> batch)
{
foreach (var tuple in batch)
{
Console.WriteLine("{0} - {1}", tuple.Item1, tuple.Item2);
}
Console.WriteLine();
}
Большинство выполнений в порядке, но иногда я получаю следующую ошибку в операторе foreach в функции WriteBatch:
& quot; Необработанное исключение: System.ArgumentException: индекс равен или больше чем длина массива, или количество элементов в словаре больше после доступного пространства от индекса до конца целевого массива. & quot;
Ошибка действительно исчезает, если основной поток спит в течение короткого времени после запуска потоков обновления и перед запуском цикла отображения. Также кажется, что оно пропадает, если предложение orderby удалено и словарь не отсортирован в запросе linq. Есть объяснения?
foreach (var tuple in batch)
оператор в функции WriteBatch выдает ошибку. Трассировка стека выглядит следующим образом:
Необработанное исключение: System.ArgumentException: индекс равен или больше чем длина массива, или количество элементов в словаре больше после доступного пространства от индекса до конца целевого массива. в System.Collections.Concurrent.ConcurrentDictionary2.System.Collections.Ge neric.ICollection & GT; .CopyTo (К массив eyValuePair2 [], индекс Int32) в System.Linq.Buffer1..ctor (источник IEnumerable1) в System.Linq.OrderedEnumerable1.d__0.MoveNext () в System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext () в MyProject.ConsoleOutputter.WriteBatch (пакет IEnumerable1) в C: \ MyProject \ ConsoleOutputter.cs: строка 10 в MyProject.Function (IEnumerable1 characterReaders, IOutputter outputter)