2012-10-30 18 views
6

Sono in esecuzione di una query PLINQ come segue:interrogazione PLINQ dando eccezione di overflow

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

Il metodo GetNextCombo è solo tornando la prossima combinazione di lettere e numeri, con possibilità fino ai miliardi/bilioni.

Ora, questo sta gettando l'eccezione quando scelgo una gamma di combinazioni maggiore della dimensione consentita di un Int32, getta sempre quando il contatore di combo è gestito è 2147483584.

ho fatto in modo che non è niente nel GetNextCombo creando una combo falso per tornare ogni volta (facendo un ritorno rendimento "234gf24fa23 ..." etc.)

l'eccezione viene gettata da 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: 

mi chiedo se c'è qualcosa che posso fare per cambiare questo problema y di non troppo pieno, qualsiasi ordine in cui faccio le cose, ecc Forse non ha la query LINQ fare un dove e selezionare, anche se ho provato questo:

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

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

ancora lo stesso di overflow.

risposta

6

Si dovrebbe essere in grado di aggirare questo utilizzando un partizionatore personalizzato. Il partizionatore predefinito scelto da PLINQ in questo caso supporta solo il numero di articoli int-range.

Vedere http://msdn.microsoft.com/en-us/library/dd997416.aspx per come procedere.

+0

non sembra funzionare per me, devi fare. ToArray o ToList() su IEnumerable I'm parallel'ing over e che creerà un overflow dello stack una volta che la dimensione è maggiore di un int. In particolare, cosa posso ignorare per farlo contare con molto tempo? –

Problemi correlati