/// <summary>
        /// Opens the query and initializes _openedQueryEnumerator and _querySettings.
        /// Called from the first MoveNext call.
        /// </summary>
        private void OpenQuery()
        {
            // Avoid opening (and failing) twice.. not only would it be bad to re-enumerate some elements, but
            // the cancellation/disposed flags are most likely stale.
            if (_hasQueryOpeningFailed)
            {
                throw new InvalidOperationException(SR.PLINQ_EnumerationPreviouslyFailed);
            }

            try
            {
                // stuff in appropriate defaults for unspecified options.
                _querySettings = _queryOperator.SpecifiedQuerySettings
                                 .WithPerExecutionSettings(_topLevelCancellationTokenSource, _topLevelDisposedFlag)
                                 .WithDefaults();

                QueryLifecycle.LogicalQueryExecutionBegin(_querySettings.QueryId);

                _openedQueryEnumerator = _queryOperator.GetOpenedEnumerator(
                    _mergeOptions, _suppressOrderPreservation, false, _querySettings);


                // Now that we have opened the query, and got our hands on a supplied cancellation token
                // we can perform an early cancellation check so that we will not do any major work if the token is already canceled.
                CancellationState.ThrowWithStandardMessageIfCanceled(_querySettings.CancellationState.ExternalCancellationToken);
            }
            catch
            {
                _hasQueryOpeningFailed = true;
                throw;
            }
        }
Example #2
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);
            }
        }
Example #3
0
        //---------------------------------------------------------------------------------------
        // This invokes the entire query tree, invoking the per-element action for each result.
        //

        internal void RunSynchronously()
        {
            Debug.Assert(_elementAction != null);

            // Get the enumerator w/out using pipelining. By the time this returns, the query
            // has been executed and we are done. We expect the return to be null.
            Shared <bool> dummyTopLevelDisposeFlag = new Shared <bool>(false);

            CancellationTokenSource dummyInternalCancellationTokenSource = new CancellationTokenSource();

            // stuff in appropriate defaults for unspecified options.
            QuerySettings settingsWithDefaults = SpecifiedQuerySettings
                                                 .WithPerExecutionSettings(dummyInternalCancellationTokenSource, dummyTopLevelDisposeFlag)
                                                 .WithDefaults();

            QueryLifecycle.LogicalQueryExecutionBegin(settingsWithDefaults.QueryId);

            IEnumerator <TInput>?enumerator = GetOpenedEnumerator(ParallelMergeOptions.FullyBuffered, true, true,
                                                                  settingsWithDefaults);

            settingsWithDefaults.CleanStateAtQueryEnd();
            Debug.Assert(enumerator == null);

            QueryLifecycle.LogicalQueryExecutionEnd(settingsWithDefaults.QueryId);
        }
        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);
        }
Example #5
0
        internal void RunSynchronously()
        {
            Shared <bool>           topLevelDisposedFlag            = new Shared <bool>(false);
            CancellationTokenSource topLevelCancellationTokenSource = new CancellationTokenSource();
            QuerySettings           querySettings = base.SpecifiedQuerySettings.WithPerExecutionSettings(topLevelCancellationTokenSource, topLevelDisposedFlag).WithDefaults();

            QueryLifecycle.LogicalQueryExecutionBegin(querySettings.QueryId);
            base.GetOpenedEnumerator(3, true, true, querySettings);
            querySettings.CleanStateAtQueryEnd();
            QueryLifecycle.LogicalQueryExecutionEnd(querySettings.QueryId);
        }
 public void Dispose()
 {
     this.m_topLevelDisposedFlag.Value = true;
     this.m_topLevelCancellationTokenSource.Cancel();
     if (this.m_openedQueryEnumerator != null)
     {
         this.m_openedQueryEnumerator.Dispose();
         this.m_querySettings.CleanStateAtQueryEnd();
     }
     QueryLifecycle.LogicalQueryExecutionEnd(this.m_querySettings.QueryId);
 }
        public void Dispose()
        {
            _topLevelDisposedFlag.Value = true;
            _topLevelCancellationTokenSource.Cancel(); // initiate internal cancellation.
            if (_openedQueryEnumerator != null)
            {
                _openedQueryEnumerator.Dispose();
                _querySettings.CleanStateAtQueryEnd();
            }

            QueryLifecycle.LogicalQueryExecutionEnd(_querySettings.QueryId);
        }
Example #8
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);
            }
        }
 private void OpenQuery()
 {
     if (this.m_hasQueryOpeningFailed)
     {
         throw new InvalidOperationException(System.Linq.SR.GetString("PLINQ_EnumerationPreviouslyFailed"));
     }
     try
     {
         this.m_querySettings = this.m_queryOperator.SpecifiedQuerySettings.WithPerExecutionSettings(this.m_topLevelCancellationTokenSource, this.m_topLevelDisposedFlag).WithDefaults();
         QueryLifecycle.LogicalQueryExecutionBegin(this.m_querySettings.QueryId);
         this.m_openedQueryEnumerator = this.m_queryOperator.GetOpenedEnumerator(this.m_mergeOptions, this.m_suppressOrderPreservation, false, this.m_querySettings);
         CancellationState.ThrowWithStandardMessageIfCanceled(this.m_querySettings.CancellationState.ExternalCancellationToken);
     }
     catch
     {
         this.m_hasQueryOpeningFailed = true;
         throw;
     }
 }