obtendo exceção de argumento no dicionário concorrente ao classificar e exibir como está sendo atualizado
Estou recebendo um difícil reproduzir erro no seguinte programa em que um número de segmentos atualizar um dicionário simultâneo em paralelo eo thread principal exibe o estado do dicionário na ordem classificada após intervalos de tempo fixo, até que todos os threads de atualização sejam concluídos.
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);
}
}
A função recebe uma lista de fluxos de caracteres e um outputter. A função mantém um dicionário concorrente de frequências de palavras de palavras lidas de cada um dos fluxos de caracteres (em paralelo). As palavras são lidas por um novo encadeamento, e o encadeamento principal produz o estado atual do dicionário (em ordem de classificação) a cada 1 milissegundo até que todos os fluxos de entrada tenham sido lidos (na prática, a saída será algo como a cada 10 segundos) mas o erro parece estar aparecendo apenas para valores muito pequenos). A função WriteBatch apenas grava no console:
public void WriteBatch(IEnumerable<Tuple<string, int>> batch)
{
foreach (var tuple in batch)
{
Console.WriteLine("{0} - {1}", tuple.Item1, tuple.Item2);
}
Console.WriteLine();
}
A maioria das execuções são boas, mas às vezes recebo o seguinte erro na instrução foreach na função WriteBatch:
"Exceção não tratada: System.ArgumentException: O índice é igual ou maior que o comprimento da matriz, ou o número de elementos no dicionário é maior que o espaço disponível do índice até o final da matriz de destino."
O erro parece desaparecer se o encadeamento principal ficar inativo por um curto período após iniciar os encadeamentos de atualização e antes de iniciar o loop de exibição. Também parece desaparecer se a cláusula orderby for removida e o dicionário não estiver classificado na consulta linq. Alguma explicação?
oforeach (var tuple in batch)
instrução na função WriteBatch dá o erro. O rastreamento de pilha é o seguinte:
Exceção não tratada: System.ArgumentException: O índice é igual ou maior que o comprimento da matriz, ou o número de elementos no dicionário é maior que o espaço disponível do índice até o final da matriz de destino. em System.Collections.Concurrent.ConcurrentDictionary2.System.Collections.Ge neric.ICollection> .CopyTo (K eyValuePair2 [] matriz, índice Int32) em System.Linq.Buffer1..ctor (IEnumerable1 source) em System.Linq.OrderedEnumerable1. d__0.MoveNext () em System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext () em MyProject.ConsoleOutputter.WriteBatch (IEnumerable1 batch) em C: \ MyProject \ ConsoleOutputter.cs: linha 10 em MyProject.Function (IEnumerable1 characterReaders, IOutputter outputter)