Пример #1
0
        //---------------------------------------------------------------------------------------
        // Executes the query and returns the results in an array.
        //

        internal TOutput[] ExecuteAndGetResultsAsArray()
        {
            QuerySettings querySettings =
                SpecifiedQuerySettings
                .WithPerExecutionSettings()
                .WithDefaults();

            QueryLifecycle.LogicalQueryExecutionBegin(querySettings.QueryId);
            try
            {
                Debug.Assert(querySettings.ExecutionMode != null);
                if (querySettings.ExecutionMode.Value == ParallelExecutionMode.Default && LimitsParallelism)
                {
                    IEnumerable <TOutput> opSequential = AsSequentialQuery(querySettings.CancellationState.ExternalCancellationToken);
                    IEnumerable <TOutput> opSequentialWithCancelChecks = CancellableEnumerable.Wrap(opSequential, querySettings.CancellationState.ExternalCancellationToken);
                    return(ExceptionAggregator.WrapEnumerable(opSequentialWithCancelChecks, querySettings.CancellationState).ToArray());
                }

                QueryResults <TOutput> results = GetQueryResults(querySettings);

                // Top-level preemptive cancellation test.
                // This handles situations where cancellation has occurred before execution commences
                // The handling for in-execution occurs in QueryTaskGroupState.QueryEnd()

                if (querySettings.CancellationState.MergedCancellationToken.IsCancellationRequested)
                {
                    querySettings.CancellationState.ExternalCancellationToken.ThrowIfCancellationRequested();
                    throw new OperationCanceledException();
                }

                if (results.IsIndexible && OutputOrdered)
                {
                    // The special array-based merge performs better if the output is ordered, because
                    // it does not have to pay for ordering. In the unordered case, we it appears that
                    // the stop-and-go merge performs a little better.
                    ArrayMergeHelper <TOutput> merger = new ArrayMergeHelper <TOutput>(SpecifiedQuerySettings, results);
                    merger.Execute();
                    TOutput[] output = merger.GetResultsAsArray();
                    querySettings.CleanStateAtQueryEnd();
                    return(output);
                }
                else
                {
                    Debug.Assert(querySettings.TaskScheduler != null);
                    PartitionedStreamMerger <TOutput> merger =
                        new PartitionedStreamMerger <TOutput>(false, ParallelMergeOptions.FullyBuffered, querySettings.TaskScheduler,
                                                              OutputOrdered, querySettings.CancellationState, querySettings.QueryId);
                    results.GivePartitionedStream(merger);
                    Debug.Assert(merger.MergeExecutor != null);
                    TOutput[]? output = merger.MergeExecutor.GetResultsAsArray();
                    querySettings.CleanStateAtQueryEnd();
                    Debug.Assert(output != null);
                    return(output);
                }
            }
            finally
            {
                QueryLifecycle.LogicalQueryExecutionEnd(querySettings.QueryId);
            }
        }
        internal IEnumerator <TOutput> GetOpenedEnumerator(ParallelMergeOptions?mergeOptions, bool suppressOrder, bool forEffect, QuerySettings querySettings)
        {
            if ((((ParallelExecutionMode)querySettings.ExecutionMode.Value) == ParallelExecutionMode.Default) && this.LimitsParallelism)
            {
                return(ExceptionAggregator.WrapEnumerable <TOutput>(this.AsSequentialQuery(querySettings.CancellationState.ExternalCancellationToken), querySettings.CancellationState).GetEnumerator());
            }
            QueryResults <TOutput> queryResults = this.GetQueryResults(querySettings);

            if (!mergeOptions.HasValue)
            {
                mergeOptions = querySettings.MergeOptions;
            }
            if (querySettings.CancellationState.MergedCancellationToken.IsCancellationRequested)
            {
                if (querySettings.CancellationState.ExternalCancellationToken.IsCancellationRequested)
                {
                    throw new OperationCanceledException(querySettings.CancellationState.ExternalCancellationToken);
                }
                throw new OperationCanceledException();
            }
            bool outputOrdered = this.OutputOrdered && !suppressOrder;
            PartitionedStreamMerger <TOutput> recipient = new PartitionedStreamMerger <TOutput>(forEffect, mergeOptions.GetValueOrDefault(), querySettings.TaskScheduler, outputOrdered, querySettings.CancellationState, querySettings.QueryId);

            queryResults.GivePartitionedStream(recipient);
            if (forEffect)
            {
                return(null);
            }
            return(recipient.MergeExecutor.GetEnumerator());
        }
        internal TOutput[] ExecuteAndGetResultsAsArray()
        {
            TOutput[]     localArray3;
            QuerySettings querySettings = base.SpecifiedQuerySettings.WithPerExecutionSettings().WithDefaults();

            QueryLifecycle.LogicalQueryExecutionBegin(querySettings.QueryId);
            try
            {
                if ((((ParallelExecutionMode)querySettings.ExecutionMode.Value) == ParallelExecutionMode.Default) && this.LimitsParallelism)
                {
                    IEnumerable <TOutput> source       = this.AsSequentialQuery(querySettings.CancellationState.ExternalCancellationToken);
                    IEnumerable <TOutput> introduced13 = CancellableEnumerable.Wrap <TOutput>(source, querySettings.CancellationState.ExternalCancellationToken);
                    return(ExceptionAggregator.WrapEnumerable <TOutput>(introduced13, querySettings.CancellationState).ToArray <TOutput>());
                }
                QueryResults <TOutput> queryResults = this.GetQueryResults(querySettings);
                if (queryResults.IsIndexible && this.OutputOrdered)
                {
                    ArrayMergeHelper <TOutput> helper = new ArrayMergeHelper <TOutput>(base.SpecifiedQuerySettings, queryResults);
                    helper.Execute();
                    TOutput[] localArray = helper.GetResultsAsArray();
                    querySettings.CleanStateAtQueryEnd();
                    return(localArray);
                }
                PartitionedStreamMerger <TOutput> recipient = new PartitionedStreamMerger <TOutput>(false, ParallelMergeOptions.FullyBuffered, querySettings.TaskScheduler, this.OutputOrdered, querySettings.CancellationState, querySettings.QueryId);
                queryResults.GivePartitionedStream(recipient);
                TOutput[] resultsAsArray = recipient.MergeExecutor.GetResultsAsArray();
                querySettings.CleanStateAtQueryEnd();
                localArray3 = resultsAsArray;
            }
            finally
            {
                QueryLifecycle.LogicalQueryExecutionEnd(querySettings.QueryId);
            }
            return(localArray3);
        }
Пример #4
0
 internal bool Aggregate(out TSource result, bool withDefaultValue)
 {
     if (this.LimitsParallelism && (((ParallelExecutionMode)base.SpecifiedQuerySettings.WithDefaults().ExecutionMode.Value) != ParallelExecutionMode.ForceParallelism))
     {
         CancellationState cancellationState = base.SpecifiedQuerySettings.CancellationState;
         if (withDefaultValue)
         {
             IEnumerable <TSource> source = CancellableEnumerable.Wrap <TSource>(base.Child.AsSequentialQuery(cancellationState.ExternalCancellationToken), cancellationState.ExternalCancellationToken);
             result = ExceptionAggregator.WrapEnumerable <TSource>(source, cancellationState).ElementAtOrDefault <TSource>(this.m_index);
         }
         else
         {
             IEnumerable <TSource> enumerable4 = CancellableEnumerable.Wrap <TSource>(base.Child.AsSequentialQuery(cancellationState.ExternalCancellationToken), cancellationState.ExternalCancellationToken);
             result = ExceptionAggregator.WrapEnumerable <TSource>(enumerable4, cancellationState).ElementAt <TSource>(this.m_index);
         }
         return(true);
     }
     using (IEnumerator <TSource> enumerator = base.GetEnumerator(3))
     {
         if (enumerator.MoveNext())
         {
             TSource current = enumerator.Current;
             result = current;
             return(true);
         }
     }
     result = default(TSource);
     return(false);
 }
Пример #5
0
        //---------------------------------------------------------------------------------------
        // The GetOpenedEnumerator method return an enumerator that walks the contents of a query.
        // The enumerator will be "opened", which means that PLINQ will start executing the query
        // immediately, even before the user calls MoveNext() for the first time.
        //
        internal IEnumerator <TOutput> GetOpenedEnumerator(ParallelMergeOptions?mergeOptions, bool suppressOrder, bool forEffect,
                                                           QuerySettings querySettings)
        {
            // If the top-level enumerator forces a premature merge, run the query sequentially.
            if (querySettings.ExecutionMode.Value == ParallelExecutionMode.Default && LimitsParallelism)
            {
                IEnumerable <TOutput> opSequential = AsSequentialQuery(querySettings.CancellationState.ExternalCancellationToken);
                return(ExceptionAggregator.WrapEnumerable(opSequential, querySettings.CancellationState).GetEnumerator());
            }

            QueryResults <TOutput> queryResults = GetQueryResults(querySettings);

            if (mergeOptions == null)
            {
                mergeOptions = querySettings.MergeOptions;
            }

            Contract.Assert(mergeOptions != null);

            // Top-level pre-emptive cancellation test.
            // This handles situations where cancellation has occured before execution commences
            // The handling for in-execution occurs in QueryTaskGroupState.QueryEnd()

            if (querySettings.CancellationState.MergedCancellationToken.IsCancellationRequested)
            {
                if (querySettings.CancellationState.ExternalCancellationToken.IsCancellationRequested)
                {
#if PFX_LEGACY_3_5
                    throw new OperationCanceledException2(querySettings.CancellationState.ExternalCancellationToken);
#else
                    throw new OperationCanceledException(querySettings.CancellationState.ExternalCancellationToken);
#endif
                }
                else
                {
                    throw new OperationCanceledException();
                }
            }

            bool orderedMerge = OutputOrdered && !suppressOrder;

            PartitionedStreamMerger <TOutput> merger = new PartitionedStreamMerger <TOutput>(forEffect, mergeOptions.GetValueOrDefault(),
                                                                                             querySettings.TaskScheduler,
                                                                                             orderedMerge,
                                                                                             querySettings.CancellationState,
                                                                                             querySettings.QueryId);

            queryResults.GivePartitionedStream(merger); // hook up the data flow between the operator-executors, starting from the merger.

            if (forEffect)
            {
                return(null);
            }

            return(merger.MergeExecutor.GetEnumerator());
        }
Пример #6
0
        //---------------------------------------------------------------------------------------
        // Executes the query and returns the results in an array.
        //

        internal TOutput[] ExecuteAndGetResultsAsArray()
        {
            QuerySettings querySettings =
                SpecifiedQuerySettings
                .WithPerExecutionSettings()
                .WithDefaults();

            QueryLifecycle.LogicalQueryExecutionBegin(querySettings.QueryId);
            try
            {
                if (querySettings.ExecutionMode.Value == ParallelExecutionMode.Default && LimitsParallelism)
                {
                    IEnumerable <TOutput> opSequential = AsSequentialQuery(querySettings.CancellationState.ExternalCancellationToken);
                    IEnumerable <TOutput> opSequentialWithCancelChecks = CancellableEnumerable.Wrap(opSequential, querySettings.CancellationState.ExternalCancellationToken);
                    return(ExceptionAggregator.WrapEnumerable(opSequentialWithCancelChecks, querySettings.CancellationState).ToArray());
                }

                QueryResults <TOutput> results = GetQueryResults(querySettings);

                if (results.IsIndexible && OutputOrdered)
                {
                    // The special array-based merge performs better if the output is ordered, because
                    // it does not have to pay for ordering. In the unordered case, we it appears that
                    // the stop-and-go merge performs a little better.
                    ArrayMergeHelper <TOutput> merger = new ArrayMergeHelper <TOutput>(SpecifiedQuerySettings, results);
                    merger.Execute();
                    TOutput[] output = merger.GetResultsAsArray();
                    querySettings.CleanStateAtQueryEnd();
                    return(output);
                }
                else
                {
                    PartitionedStreamMerger <TOutput> merger =
                        new PartitionedStreamMerger <TOutput>(false, ParallelMergeOptions.FullyBuffered, querySettings.TaskScheduler,
                                                              OutputOrdered, querySettings.CancellationState, querySettings.QueryId);
                    results.GivePartitionedStream(merger);
                    TOutput[] output = merger.MergeExecutor.GetResultsAsArray();
                    querySettings.CleanStateAtQueryEnd();
                    return(output);
                }
            }
            finally
            {
                QueryLifecycle.LogicalQueryExecutionEnd(querySettings.QueryId);
            }
        }
Пример #7
0
        /// <summary>
        /// Executes the query, either sequentially or in parallel, depending on the query execution mode and
        /// whether a premature merge was inserted by this ElementAt operator.
        /// </summary>
        /// <param name="result">result</param>
        /// <param name="withDefaultValue">withDefaultValue</param>
        /// <returns>whether an element with this index exists</returns>
        internal bool Aggregate(out TSource result, bool withDefaultValue)
        {
            // If we were to insert a premature merge before this ElementAt, and we are executing in conservative mode, run the whole query
            // sequentially.
            if (LimitsParallelism && SpecifiedQuerySettings.WithDefaults().ExecutionMode.Value != ParallelExecutionMode.ForceParallelism)
            {
                CancellationState cancelState = SpecifiedQuerySettings.CancellationState;
                if (withDefaultValue)
                {
                    IEnumerable <TSource> childAsSequential     = Child.AsSequentialQuery(cancelState.ExternalCancellationToken);
                    IEnumerable <TSource> childWithCancelChecks = CancellableEnumerable.Wrap(childAsSequential, cancelState.ExternalCancellationToken);
                    result = ExceptionAggregator.WrapEnumerable(childWithCancelChecks, cancelState).ElementAtOrDefault(_index);
                }
                else
                {
                    IEnumerable <TSource> childAsSequential     = Child.AsSequentialQuery(cancelState.ExternalCancellationToken);
                    IEnumerable <TSource> childWithCancelChecks = CancellableEnumerable.Wrap(childAsSequential, cancelState.ExternalCancellationToken);
                    result = ExceptionAggregator.WrapEnumerable(childWithCancelChecks, cancelState).ElementAt(_index);
                }
                return(true);
            }

            using (IEnumerator <TSource> e = GetEnumerator(ParallelMergeOptions.FullyBuffered))
            {
                if (e.MoveNext())
                {
                    TSource current = e.Current;
                    Contract.Assert(!e.MoveNext(), "expected enumerator to be empty");
                    result = current;
                    return(true);
                }
            }

            result = default(TSource);
            return(false);
        }