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
- RangeBaseAutomationPeer.cs
- XPathDocumentNavigator.cs
- Shape.cs
- LineVisual.cs
- OperationResponse.cs
- ServiceTimeoutsBehavior.cs
- XmlDocument.cs
- DataRelationPropertyDescriptor.cs
- BitmapCache.cs
- EntitySetBaseCollection.cs
- TraceHelpers.cs
- FileEnumerator.cs
- Symbol.cs
- Empty.cs
- GridItemCollection.cs
- RequestQueryProcessor.cs
- DependencyPropertyKind.cs
- RewritingValidator.cs
- DictionaryGlobals.cs
- AnchoredBlock.cs
- SmtpNtlmAuthenticationModule.cs
- PrintDocument.cs
- PersonalizablePropertyEntry.cs
- HandlerBase.cs
- DbDataRecord.cs
- DataGridViewLinkCell.cs
- Quaternion.cs
- ResourcesBuildProvider.cs
- PolicyValidationException.cs
- ShapeTypeface.cs
- MatrixKeyFrameCollection.cs
- OleDbConnectionFactory.cs
- DiscoveryServiceExtension.cs
- NativeCompoundFileAPIs.cs
- NullableConverter.cs
- SharedStatics.cs
- DocumentViewerConstants.cs
- MsmqNonTransactedPoisonHandler.cs
- SimpleWorkerRequest.cs
- Attributes.cs
- ButtonBase.cs
- CompilationLock.cs
- CodeTypeReferenceExpression.cs
- ScrollProviderWrapper.cs
- ConstructorBuilder.cs
- MessageSmuggler.cs
- EdmToObjectNamespaceMap.cs
- ListViewDeleteEventArgs.cs
- WindowsToolbar.cs
- BackStopAuthenticationModule.cs
- RolePrincipal.cs
- DocumentPageView.cs
- TimeSpanConverter.cs
- TimeSpanSecondsOrInfiniteConverter.cs
- AsymmetricCryptoHandle.cs
- HitTestFilterBehavior.cs
- storepermission.cs
- InheritablePropertyChangeInfo.cs
- AssemblyCacheEntry.cs
- ElementHostAutomationPeer.cs
- MatrixTransform.cs
- SoapExtensionTypeElement.cs
- SourceFilter.cs
- WebBaseEventKeyComparer.cs
- LogArchiveSnapshot.cs
- ControllableStoryboardAction.cs
- HealthMonitoringSection.cs
- Duration.cs
- TemplateComponentConnector.cs
- BackgroundWorker.cs
- SessionState.cs
- SchemaContext.cs
- BitmapMetadataEnumerator.cs
- ServiceModelTimeSpanValidator.cs
- RIPEMD160.cs
- PackageRelationshipSelector.cs
- BindingSource.cs
- BamlRecords.cs
- DocumentViewerConstants.cs
- CompilerResults.cs
- ValidationResults.cs
- ClassData.cs
- TrackingProfileSerializer.cs
- DataSvcMapFile.cs
- DataGridComponentEditor.cs
- BaseResourcesBuildProvider.cs
- RequiredFieldValidator.cs
- XmlILOptimizerVisitor.cs
- TypeElement.cs
- DesignerActionPropertyItem.cs
- PlainXmlSerializer.cs
- LinearQuaternionKeyFrame.cs
- SqlCacheDependency.cs
- ComponentCollection.cs
- CacheManager.cs
- XmlEventCache.cs
- SoapMessage.cs
- HttpPostServerProtocol.cs
- DataGridViewAutoSizeColumnModeEventArgs.cs
- ServiceOperationHelpers.cs