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
- GroupJoinQueryOperator.cs
- IpcPort.cs
- HttpModuleAction.cs
- PrimitiveDataContract.cs
- ContextStaticAttribute.cs
- DefaultAssemblyResolver.cs
- LowerCaseStringConverter.cs
- unitconverter.cs
- DbMetaDataCollectionNames.cs
- DataBindingCollectionEditor.cs
- NominalTypeEliminator.cs
- DataGridViewCellParsingEventArgs.cs
- EventLogPermissionAttribute.cs
- SelectionItemPattern.cs
- CacheAxisQuery.cs
- BindingContext.cs
- xdrvalidator.cs
- safesecurityhelperavalon.cs
- DesignerLabelAdapter.cs
- TreeView.cs
- XmlWellformedWriter.cs
- ResourceReferenceExpression.cs
- AttributeCollection.cs
- BrowserCapabilitiesFactory35.cs
- MethodBody.cs
- XmlChildNodes.cs
- TCEAdapterGenerator.cs
- PageBuildProvider.cs
- Delay.cs
- XmlDocumentFragment.cs
- CheckBox.cs
- ListViewGroupItemCollection.cs
- ProvidersHelper.cs
- BrowsableAttribute.cs
- MexHttpBindingCollectionElement.cs
- BindUriHelper.cs
- ListenerHandler.cs
- RadialGradientBrush.cs
- TrackingConditionCollection.cs
- Proxy.cs
- DocumentApplication.cs
- ContainerUtilities.cs
- EditingCommands.cs
- TemplateControlBuildProvider.cs
- HiddenFieldDesigner.cs
- ContentControl.cs
- UIElement.cs
- RightsManagementSuppressedStream.cs
- HtmlTableCellCollection.cs
- TdsParameterSetter.cs
- AutomationPatternInfo.cs
- UriExt.cs
- WebPartCollection.cs
- Control.cs
- DocumentPageViewAutomationPeer.cs
- CodeEventReferenceExpression.cs
- QueueProcessor.cs
- FormattedTextSymbols.cs
- WmlLiteralTextAdapter.cs
- FloatUtil.cs
- DbConnectionPoolOptions.cs
- DataPagerCommandEventArgs.cs
- AlternateViewCollection.cs
- DbDataSourceEnumerator.cs
- WebConfigurationHostFileChange.cs
- PartitionedStreamMerger.cs
- CodeAccessSecurityEngine.cs
- InstanceNormalEvent.cs
- Matrix3DStack.cs
- XmlBinaryReader.cs
- NavigationWindowAutomationPeer.cs
- DataGridViewAdvancedBorderStyle.cs
- RegexMatchCollection.cs
- ListChangedEventArgs.cs
- SettingsSavedEventArgs.cs
- PointConverter.cs
- XmlCharCheckingReader.cs
- DefaultAssemblyResolver.cs
- XmlComment.cs
- TemplateColumn.cs
- ControlDesigner.cs
- InkCanvas.cs
- Calendar.cs
- DbConnectionInternal.cs
- basevalidator.cs
- XmlTextReaderImpl.cs
- ActivityCollectionMarkupSerializer.cs
- DataBindingCollectionConverter.cs
- TypeResolver.cs
- OutputCacheSettings.cs
- ValueOfAction.cs
- securitycriticaldataClass.cs
- DataGridViewBand.cs
- ProvideValueServiceProvider.cs
- DataSourceControl.cs
- ObjectResult.cs
- LockedActivityGlyph.cs
- DataTableReaderListener.cs
- EasingQuaternionKeyFrame.cs
- BaseDataBoundControl.cs