【问题标题】:PLINQ query giving overflow exceptionPLINQ 查询给出溢出异常
【发布时间】:2012-10-30 02:46:02
【问题描述】:

我正在运行如下 PLINQ 查询:

ParallelQuery<string> winningCombos = from n in nextComboMaker.GetNextCombo()
                                              .AsParallel().WithCancellation(_cancelSource.Token)
                                              where ComboWasAWinner(n) 
                                              select n;

ConcurrentBag<string> wins = new ConcurrentBag<string>();

foreach (var winningCombo in winningCombos)
{
        wins.Add(winningCombo);
        if (wins.Count == _maxWinsAllowed)
            break;
}

GetNextCombo 方法只是返回字母和数字的下一个组合,可能性高达数十亿/万亿。

现在,当我选择的组合范围大于 Int32 的允许大小时,它会抛出异常,当它运行的组合计数器为 2147483584 时,它总是会抛出异常。

我通过创建一个每次返回的假组合来确保 GetNextCombo 中没有任何内容(执行 yield return "234gf24fa23..." 等)

LINQ 正在抛出异常:

System.AggregateException was unhandled by user code
  Message=One or more errors occurred.
  Source=System.Core
  StackTrace:
       at System.Linq.Parallel.QueryTaskGroupState.QueryEnd(Boolean userInitiatedDispose)
       at System.Linq.Parallel.MergeExecutor`1.Execute[TKey](PartitionedStream`2 partitions, Boolean ignoreOutput, ParallelMergeOptions options, TaskScheduler taskScheduler, Boolean isOrdered, CancellationState cancellationState, Int32 queryId)
       at System.Linq.Parallel.PartitionedStreamMerger`1.Receive[TKey](PartitionedStream`2 partitionedStream)
       at System.Linq.Parallel.ForAllOperator`1.WrapPartitionedStream[TKey](PartitionedStream`2 inputStream, IPartitionedStreamRecipient`1 recipient, Boolean preferStriping, QuerySettings settings)
       at System.Linq.Parallel.UnaryQueryOperator`2.UnaryQueryOperatorResults.ChildResultsRecipient.Receive[TKey](PartitionedStream`2 inputStream)
       at System.Linq.Parallel.WhereQueryOperator`1.WrapPartitionedStream[TKey](PartitionedStream`2 inputStream, IPartitionedStreamRecipient`1 recipient, Boolean preferStriping, QuerySettings settings)
       at System.Linq.Parallel.UnaryQueryOperator`2.UnaryQueryOperatorResults.ChildResultsRecipient.Receive[TKey](PartitionedStream`2 inputStream)
       at System.Linq.Parallel.ScanQueryOperator`1.ScanEnumerableQueryOperatorResults.GivePartitionedStream(IPartitionedStreamRecipient`1 recipient)
       at System.Linq.Parallel.UnaryQueryOperator`2.UnaryQueryOperatorResults.GivePartitionedStream(IPartitionedStreamRecipient`1 recipient)
       at System.Linq.Parallel.UnaryQueryOperator`2.UnaryQueryOperatorResults.GivePartitionedStream(IPartitionedStreamRecipient`1 recipient)
       at System.Linq.Parallel.QueryOperator`1.GetOpenedEnumerator(Nullable`1 mergeOptions, Boolean suppressOrder, Boolean forEffect, QuerySettings querySettings)
       at System.Linq.Parallel.ForAllOperator`1.RunSynchronously()
       at StockWiz.Library.PLINQArrayProcessor.DoProcessing() in C:\Users\dad\Documents\BitBucket\stockwiz_clone\stockwiz\StockWiz.Library\PLINQArrayProcessor.cs:line 50
       at System.Threading.Tasks.Task.Execute()
  InnerException: System.OverflowException
       Message=Arithmetic operation resulted in an overflow.
       Source=System.Core
       StackTrace:
            at System.Linq.Parallel.PartitionedDataSource`1.ContiguousChunkLazyEnumerator.MoveNext(T& currentElement, Int32& currentKey)
            at System.Linq.Parallel.WhereQueryOperator`1.WhereQueryOperatorEnumerator`1.MoveNext(TInputOutput& currentElement, TKey& currentKey)
            at System.Linq.Parallel.ForAllOperator`1.ForAllEnumerator`1.MoveNext(TInput& currentElement, Int32& currentKey)
            at System.Linq.Parallel.ForAllSpoolingTask`2.SpoolingWork()
            at System.Linq.Parallel.SpoolingTaskBase.Work()
            at System.Linq.Parallel.QueryTask.BaseWork(Object unused)
            at System.Threading.Tasks.Task.Execute()
       InnerException: 

我想知道是否可以做任何事情来更改此查询以使其不溢出、我执行操作的任何顺序等。也许没有 linq 查询执行 where 和 select,尽管我已经尝试过:

 var query = nextComboMaker.GetNextCombo().AsParallel();

 query.ForAll(x => if(ComboWasAWinner(x) wins.Add(x) );

还是一样的溢出。

【问题讨论】:

    标签: c# linq task-parallel-library plinq


    【解决方案1】:

    您应该能够通过使用自定义分区程序来解决这个问题。在这种情况下 PLINQ 选择的默认分区器仅支持 int-range 项目数。

    请参阅http://msdn.microsoft.com/en-us/library/dd997416.aspx 了解如何执行此操作。

    【讨论】:

    • 似乎对我不起作用,你必须在我正在并行处理的 IEnumerable 上执行 .ToArray 或 ToList() ,一旦大小大于一个整数。我可以具体覆盖什么以使其长计数?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-27
    • 2017-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多