Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / System / Linq / Parallel / Utils / ExceptionAggregator.cs / 1305376 / ExceptionAggregator.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // // ExceptionAggregator.cs // //[....] // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System; using System.Collections.Generic; using System.Threading; namespace System.Linq.Parallel { internal static class ExceptionAggregator { ////// WrapEnumerable.ExceptionAggregator wraps the enumerable with another enumerator that will /// catch exceptions, and wrap each with an AggregateException. /// /// If PLINQ decides to execute a query sequentially, we will reuse LINQ-to-objects /// implementations for the different operators. However, we still need to throw /// AggregateException in the cases when parallel execution would have thrown an /// AggregateException. Thus, we introduce a wrapper enumerator that catches exceptions /// and wraps them with an AggregateException. /// internal static IEnumerableWrapEnumerable (IEnumerable source, CancellationState cancellationState) { using (IEnumerator enumerator = source.GetEnumerator()) { while (true) { TElement elem = default(TElement); try { if (!enumerator.MoveNext()) { yield break; } elem = enumerator.Current; } catch (ThreadAbortException) { // Do not wrap ThreadAbortExceptions throw; } catch (Exception ex) { ThrowOCEorAggregateException(ex, cancellationState); } yield return elem; } } } /// /// A variant of WrapEnumerable that accepts a QueryOperatorEnumerator{,} instead of an IEnumerable{}. /// The code duplication is necessary to avoid extra virtual method calls that would otherwise be needed to /// convert the QueryOperatorEnumerator{,} to an IEnumerator{}. /// internal static IEnumerableWrapQueryEnumerator (QueryOperatorEnumerator source, CancellationState cancellationState) { TElement elem = default(TElement); TIgnoreKey ignoreKey = default(TIgnoreKey); try { while (true) { try { if (!source.MoveNext(ref elem, ref ignoreKey)) { yield break; } } catch (ThreadAbortException) { // Do not wrap ThreadAbortExceptions throw; } catch (Exception ex) { ThrowOCEorAggregateException(ex, cancellationState); } yield return elem; } } finally { source.Dispose(); } } /// /// Accepts an exception, wraps it as if it was crossing the parallel->sequential boundary, and throws the /// wrapped exception. In sequential fallback cases, we use this method to throw exceptions that are consistent /// with exceptions thrown by PLINQ when the query is executed by worker tasks. /// /// The exception will be wrapped into an AggregateException, except for the case when the query is being /// legitimately cancelled, in which case we will propagate the CancellationException with the appropriate /// token. /// internal static void ThrowOCEorAggregateException(Exception ex, CancellationState cancellationState) { if (ThrowAnOCE(ex, cancellationState)) { CancellationState.ThrowWithStandardMessageIfCanceled( cancellationState.ExternalCancellationToken); } else { throw new AggregateException(ex); } } ////// Wraps a function with a try/catch that morphs all exceptions into AggregateException. /// ///The input argument type. ///The return value type. /// A function to use internally. /// The cancellation state to use. ///A new function containing exception wrapping logic. internal static FuncWrapFunc (Func f, CancellationState cancellationState) { return t => { U retval = default(U); try { retval = f(t); } catch (ThreadAbortException) { // Do not wrap ThreadAbortExceptions throw; } catch (Exception ex) { ThrowOCEorAggregateException(ex, cancellationState); } return retval; }; } // return: true ==> throw an OCE(externalCT) // false ==> thrown an AggregateException(ex). private static bool ThrowAnOCE(Exception ex, CancellationState cancellationState) { // if the query has been canceled and the exception represents this, we want to throw OCE // but otherwise we want to throw an AggregateException to mimic normal Plinq operation // See QueryTaskGroupState.WaitAll for the main plinq exception handling logic. // check for co-operative cancellation. OperationCanceledException cancelEx = ex as OperationCanceledException; if (cancelEx != null && cancelEx.CancellationToken == cancellationState.ExternalCancellationToken && cancellationState.ExternalCancellationToken.IsCancellationRequested) { return true; // let the OCE(extCT) be rethrown. } // check for external cancellation which triggered the mergedToken. if (cancelEx != null && cancelEx.CancellationToken == cancellationState.MergedCancellationToken && cancellationState.MergedCancellationToken.IsCancellationRequested && cancellationState.ExternalCancellationToken.IsCancellationRequested) { return true; // convert internal cancellation back to OCE(extCT). } return false; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // // ExceptionAggregator.cs // // [....] // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System; using System.Collections.Generic; using System.Threading; namespace System.Linq.Parallel { internal static class ExceptionAggregator { ////// WrapEnumerable.ExceptionAggregator wraps the enumerable with another enumerator that will /// catch exceptions, and wrap each with an AggregateException. /// /// If PLINQ decides to execute a query sequentially, we will reuse LINQ-to-objects /// implementations for the different operators. However, we still need to throw /// AggregateException in the cases when parallel execution would have thrown an /// AggregateException. Thus, we introduce a wrapper enumerator that catches exceptions /// and wraps them with an AggregateException. /// internal static IEnumerableWrapEnumerable (IEnumerable source, CancellationState cancellationState) { using (IEnumerator enumerator = source.GetEnumerator()) { while (true) { TElement elem = default(TElement); try { if (!enumerator.MoveNext()) { yield break; } elem = enumerator.Current; } catch (ThreadAbortException) { // Do not wrap ThreadAbortExceptions throw; } catch (Exception ex) { ThrowOCEorAggregateException(ex, cancellationState); } yield return elem; } } } /// /// A variant of WrapEnumerable that accepts a QueryOperatorEnumerator{,} instead of an IEnumerable{}. /// The code duplication is necessary to avoid extra virtual method calls that would otherwise be needed to /// convert the QueryOperatorEnumerator{,} to an IEnumerator{}. /// internal static IEnumerableWrapQueryEnumerator (QueryOperatorEnumerator source, CancellationState cancellationState) { TElement elem = default(TElement); TIgnoreKey ignoreKey = default(TIgnoreKey); try { while (true) { try { if (!source.MoveNext(ref elem, ref ignoreKey)) { yield break; } } catch (ThreadAbortException) { // Do not wrap ThreadAbortExceptions throw; } catch (Exception ex) { ThrowOCEorAggregateException(ex, cancellationState); } yield return elem; } } finally { source.Dispose(); } } /// /// Accepts an exception, wraps it as if it was crossing the parallel->sequential boundary, and throws the /// wrapped exception. In sequential fallback cases, we use this method to throw exceptions that are consistent /// with exceptions thrown by PLINQ when the query is executed by worker tasks. /// /// The exception will be wrapped into an AggregateException, except for the case when the query is being /// legitimately cancelled, in which case we will propagate the CancellationException with the appropriate /// token. /// internal static void ThrowOCEorAggregateException(Exception ex, CancellationState cancellationState) { if (ThrowAnOCE(ex, cancellationState)) { CancellationState.ThrowWithStandardMessageIfCanceled( cancellationState.ExternalCancellationToken); } else { throw new AggregateException(ex); } } ////// Wraps a function with a try/catch that morphs all exceptions into AggregateException. /// ///The input argument type. ///The return value type. /// A function to use internally. /// The cancellation state to use. ///A new function containing exception wrapping logic. internal static FuncWrapFunc (Func f, CancellationState cancellationState) { return t => { U retval = default(U); try { retval = f(t); } catch (ThreadAbortException) { // Do not wrap ThreadAbortExceptions throw; } catch (Exception ex) { ThrowOCEorAggregateException(ex, cancellationState); } return retval; }; } // return: true ==> throw an OCE(externalCT) // false ==> thrown an AggregateException(ex). private static bool ThrowAnOCE(Exception ex, CancellationState cancellationState) { // if the query has been canceled and the exception represents this, we want to throw OCE // but otherwise we want to throw an AggregateException to mimic normal Plinq operation // See QueryTaskGroupState.WaitAll for the main plinq exception handling logic. // check for co-operative cancellation. OperationCanceledException cancelEx = ex as OperationCanceledException; if (cancelEx != null && cancelEx.CancellationToken == cancellationState.ExternalCancellationToken && cancellationState.ExternalCancellationToken.IsCancellationRequested) { return true; // let the OCE(extCT) be rethrown. } // check for external cancellation which triggered the mergedToken. if (cancelEx != null && cancelEx.CancellationToken == cancellationState.MergedCancellationToken && cancellationState.MergedCancellationToken.IsCancellationRequested && cancellationState.ExternalCancellationToken.IsCancellationRequested) { return true; // convert internal cancellation back to OCE(extCT). } return false; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ToolStripItemRenderEventArgs.cs
- WithParamAction.cs
- CookieHandler.cs
- GZipDecoder.cs
- _BufferOffsetSize.cs
- XmlSerializationWriter.cs
- XmlSchemaValidator.cs
- UnsafeNativeMethods.cs
- RSAPKCS1KeyExchangeDeformatter.cs
- DrawingContext.cs
- MachineSettingsSection.cs
- ListControlStringCollectionEditor.cs
- WebPartChrome.cs
- DBConnectionString.cs
- Page.cs
- PropertyNames.cs
- RequestQueryProcessor.cs
- ModelTreeEnumerator.cs
- PlanCompiler.cs
- ObjectStateManagerMetadata.cs
- HttpRequest.cs
- Knowncolors.cs
- StructuralType.cs
- VectorCollectionConverter.cs
- ListViewSelectEventArgs.cs
- XmlAggregates.cs
- XmlDataSource.cs
- CroppedBitmap.cs
- DataGridParentRows.cs
- ListViewTableRow.cs
- Nodes.cs
- TextUtf8RawTextWriter.cs
- ResourceIDHelper.cs
- QilStrConcat.cs
- TextTrailingWordEllipsis.cs
- TextRangeEdit.cs
- WebRequestModulesSection.cs
- LicFileLicenseProvider.cs
- TagPrefixAttribute.cs
- JsonEnumDataContract.cs
- JsonObjectDataContract.cs
- DbDataRecord.cs
- TypeResolver.cs
- RijndaelManaged.cs
- AbandonedMutexException.cs
- ObjectDataSourceEventArgs.cs
- XsdCachingReader.cs
- SamlAdvice.cs
- NetworkInformationPermission.cs
- ImageListUtils.cs
- DrawingGroup.cs
- WriterOutput.cs
- XslCompiledTransform.cs
- basemetadatamappingvisitor.cs
- ActivityDefaults.cs
- RenamedEventArgs.cs
- SelectingProviderEventArgs.cs
- BitmapEffectDrawingContent.cs
- ConfigurationConverterBase.cs
- FontConverter.cs
- ApplicationServiceManager.cs
- MatrixAnimationBase.cs
- ModuleBuilderData.cs
- CodeAttachEventStatement.cs
- HostProtectionException.cs
- UnknownBitmapEncoder.cs
- CustomError.cs
- ClientBase.cs
- DiagnosticTrace.cs
- WorkflowMessageEventHandler.cs
- TextEditorTables.cs
- SimpleTypeResolver.cs
- MessageSmuggler.cs
- ConfigurationSettings.cs
- GlyphShapingProperties.cs
- ImmutableCollection.cs
- GlyphRun.cs
- CodeTypeParameterCollection.cs
- DataPager.cs
- DispatcherTimer.cs
- SkipQueryOptionExpression.cs
- GestureRecognizer.cs
- FormViewUpdatedEventArgs.cs
- FileReservationCollection.cs
- DataGridRow.cs
- Separator.cs
- GridViewUpdateEventArgs.cs
- RequestCacheValidator.cs
- InputScope.cs
- QilReplaceVisitor.cs
- ModelItem.cs
- ImageClickEventArgs.cs
- QuaternionConverter.cs
- FileInfo.cs
- TransformValueSerializer.cs
- SoapCommonClasses.cs
- OuterProxyWrapper.cs
- ByteStack.cs
- Profiler.cs
- FixedPageStructure.cs