2012-10-30 33 views
6

Tôi đang chạy một truy vấn PLINQ như sau:PLINQ truy vấn cho tràn ngoại lệ

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; 
} 

Phương pháp GetNextCombo chỉ là trở về sự kết hợp tiếp theo của các chữ cái và con số, với khả năng lên đến hàng tỷ/nghìn tỷ.

Bây giờ này là ném ngoại lệ khi tôi chọn một loạt các kết hợp lớn hơn kích thước cho phép của một Int32, nó luôn luôn ném khi bộ đếm của combo nó chạy là 2147483584.

Tôi đã thực hiện chắc chắn nó không có gì trong GetNextCombo bằng cách tạo ra một combo giả để trở lại mỗi khi (làm một yield return "234gf24fa23 ..." vv)

Trường hợp ngoại lệ được ném ra bởi 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: 

tôi tự hỏi nếu có bất cứ điều gì tôi có thể làm để thay đổi quer này y để không tràn, bất kỳ thứ tự mà tôi làm việc, vv Có lẽ không có truy vấn LINQ làm một nơi và chọn, mặc dù tôi đã cố gắng này:

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

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

vẫn tràn cùng.

Trả lời

6

Bạn sẽ có thể thực hiện việc này bằng cách sử dụng trình phân vùng tùy chỉnh. Trình phân vùng mặc định được PLINQ chọn trong trường hợp này chỉ hỗ trợ số lượng mục trong phạm vi.

Xem http://msdn.microsoft.com/en-us/library/dd997416.aspx để biết cách thực hiện việc này.

+0

dường như không hoạt động đối với tôi, bạn phải làm .ToArray hoặc ToList() trên IEnumerable Tôi song song và điều đó sẽ tạo ra tràn ngăn xếp khi kích thước lớn hơn một int. Tôi có thể ghi đè cụ thể những gì để làm cho nó được đếm lâu? –

Các vấn đề liên quan