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