C# PLINQ Ошибка
Всем привет, у меня такая задача я считываю большой txt файл и работаю с каждым словом в нем. Без многопоточности всё работает как надо. Но я хочу распараллелить её. Параллельно обрабатывать несколько слов. За обработку каждого слова отвечает void функция принимающая string - void
text.AsParallel()
.Select(str => str.ToUpper())
.Where(str => str.Length >= countCharacter &&
Regex.IsMatch(str, "[A-Z]+"))
.ForAll(str =>
{
checkNode(str);
});
private void checkNode(string node)
{
int size = node.Length;
int countSkip = 0;
while (countSkip + countCharacter <= size)
{
string characters = getConcatStrings(node.Skip(countSkip).Take(countCharacter).ToList());
countSkip++;
if (pairs.ContainsKey(characters))
pairs[characters]++;
else
pairs.TryAdd(characters, 1);
}
}
- Без расспараллеливания
foreach (var str in text
.Select(str => str.ToUpper())
.Where(str => str.Length >= countCharacter &&
Regex.IsMatch(str, "[A-Z]+"))
checkNode(str);
- Тоже самое пытаюсь сделать, но уже с PLINQ
text.AsParallel()
.ForAll(str =>
{
str = str.ToUpper();
if (str.Length >= countCharacter
&& Regex.IsMatch(str, "[A-Z]+"))
checkNode(str);
});
Во втором случае выдает ошибку
System.AggregateException
HResult=0x80131500
Сообщение = Произошла одна или несколько ошибок.
Источник = System.Core
Трассировка стека:
в System.Linq.Parallel.QueryTaskGroupState.QueryEnd(Boolean userInitiatedDispose)
в System.Linq.Parallel.SpoolingTask.SpoolForAll[TInputOutput,TIgnoreKey](QueryTaskGroupState groupState, PartitionedStream`2 partitions, TaskScheduler taskScheduler)
в System.Linq.Parallel.DefaultMergeHelper`2.System.Linq.Parallel.IMergeHelper<TInputOutput>.Execute()
в System.Linq.Parallel.MergeExecutor`1.Execute()
в System.Linq.Parallel.MergeExecutor`1.Execute[TKey](PartitionedStream`2 partitions, Boolean ignoreOutput, ParallelMergeOptions options, TaskScheduler taskScheduler, Boolean isOrdered, CancellationState cancellationState, Int32 queryId)
в System.Linq.Parallel.PartitionedStreamMerger`1.Receive[TKey](PartitionedStream`2 partitionedStream)
в System.Linq.Parallel.ForAllOperator`1.WrapPartitionedStream[TKey](PartitionedStream`2 inputStream, IPartitionedStreamRecipient`1 recipient, Boolean preferStriping, QuerySettings settings)
в System.Linq.Parallel.UnaryQueryOperator`2.UnaryQueryOperatorResults.ChildResultsRecipient.Receive[TKey](PartitionedStream`2 inputStream)
в System.Linq.Parallel.ListQueryResults`1.GivePartitionedStream(IPartitionedStreamRecipient`1 recipient)
в System.Linq.Parallel.UnaryQueryOperator`2.UnaryQueryOperatorResults.GivePartitionedStream(IPartitionedStreamRecipient`1 recipient)
в System.Linq.Parallel.QueryOperator`1.GetOpenedEnumerator(Nullable`1 mergeOptions, Boolean suppressOrder, Boolean forEffect, QuerySettings querySettings)
в System.Linq.Parallel.ForAllOperator`1.RunSynchronously()
в System.Linq.ParallelEnumerable.ForAll[TSource](ParallelQuery`1 source, Action`1 action)
в TaskTextWorker.TextWorker.Start() в C:\Users\danil\source\repos\TaskTextWorker\TaskTextWorker\TextWorker.cs:строка 43
в TaskTextWorker.TextWorker.GetStatistics(List`1 text, Int32 countTop, Int32 countCharacter) в C:\Users\danil\source\repos\TaskTextWorker\TaskTextWorker\TextWorker.cs:строка 28
в TaskTextWorker.Program.Main(String[] args) в C:\Users\danil\source\repos\TaskTextWorker\TaskTextWorker\Program.cs:строка 17
Внутреннее исключение 1:
ArgumentException: Длина результирующего массива недостаточна. Проверьте значения destIndex и length, а также нижние границы массива.
Вопрос что делать и почему так ?
Ответы (1 шт):
Автор решения: DanBit
→ Ссылка
Так я ипользовал контейнеры List и Dictionary<string, ushort> они являются не потоко безопасными, поэтому когда заменил на ConcurrentDictionary<string, ushort> и на Dictionary<string, ushort>. Насколько моё решение правильно с точни зрения вычислений пока не знаю, но хотяб собирается и работает.