Code:
/ 4.0 / 4.0 / untmp / 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 IEnumerable WrapEnumerable(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 IEnumerable WrapQueryEnumerator(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 Func WrapFunc(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
- EntityParameter.cs
- MemberDomainMap.cs
- CodeCompileUnit.cs
- LiteralLink.cs
- Section.cs
- _ServiceNameStore.cs
- JsonWriterDelegator.cs
- RoleExceptions.cs
- RadialGradientBrush.cs
- HttpListenerContext.cs
- PasswordDeriveBytes.cs
- ColorMatrix.cs
- CompiledRegexRunner.cs
- ClipboardProcessor.cs
- TextWriter.cs
- KeyValuePairs.cs
- DataContractJsonSerializerOperationBehavior.cs
- BaseParagraph.cs
- CapabilitiesAssignment.cs
- SymDocumentType.cs
- FormViewInsertedEventArgs.cs
- WorkflowHostingResponseContext.cs
- TimerElapsedEvenArgs.cs
- MimeMultiPart.cs
- TrustManager.cs
- PackUriHelper.cs
- ClientUtils.cs
- SslStream.cs
- ContourSegment.cs
- TargetParameterCountException.cs
- TextFormatter.cs
- ScrollItemProviderWrapper.cs
- EventMappingSettings.cs
- AccessedThroughPropertyAttribute.cs
- Monitor.cs
- DrawingDrawingContext.cs
- WebBaseEventKeyComparer.cs
- OdbcHandle.cs
- HtmlInputPassword.cs
- RegionInfo.cs
- DrawToolTipEventArgs.cs
- RectangleHotSpot.cs
- SelectionPatternIdentifiers.cs
- XmlDictionaryReaderQuotas.cs
- ValidatingPropertiesEventArgs.cs
- WmlValidatorAdapter.cs
- ImageKeyConverter.cs
- MobileUserControl.cs
- TCEAdapterGenerator.cs
- WebHttpSecurityModeHelper.cs
- DoubleMinMaxAggregationOperator.cs
- HostProtectionException.cs
- DataRowCollection.cs
- ApplicationDirectoryMembershipCondition.cs
- DataService.cs
- DefaultObjectMappingItemCollection.cs
- DecoratedNameAttribute.cs
- PathFigureCollection.cs
- DocumentViewerAutomationPeer.cs
- XmlSchema.cs
- AsnEncodedData.cs
- FlowLayoutPanel.cs
- CodeObject.cs
- TabControlToolboxItem.cs
- _LoggingObject.cs
- DataServicePagingProviderWrapper.cs
- DelegateOutArgument.cs
- PngBitmapDecoder.cs
- X509ChainElement.cs
- XmlTextReaderImplHelpers.cs
- Publisher.cs
- WindowsFormsEditorServiceHelper.cs
- PseudoWebRequest.cs
- WebWorkflowRole.cs
- ConnectionsZone.cs
- ResourcesChangeInfo.cs
- MouseActionConverter.cs
- LexicalChunk.cs
- ClearTypeHintValidation.cs
- ImageFormatConverter.cs
- ObjectDataSourceEventArgs.cs
- XmlTextEncoder.cs
- CodeDirectiveCollection.cs
- DateTimeConverter2.cs
- ContentValidator.cs
- InvalidProgramException.cs
- Registry.cs
- SqlAggregateChecker.cs
- MimeReflector.cs
- TCEAdapterGenerator.cs
- BlurBitmapEffect.cs
- ExpressionConverter.cs
- CommandPlan.cs
- PerformanceCounterManager.cs
- CompoundFileStorageReference.cs
- WorkItem.cs
- WebPartAddingEventArgs.cs
- XmlQualifiedNameTest.cs
- smtpconnection.cs
- TemplateGroupCollection.cs