未验证 提交 f4ed7672 编写于 作者: S Stephen Toub 提交者: GitHub

Fix assert / ObjectDisposedException in PLINQ handling of AggregateException (#47711)

PLINQ's QueryTaskGroupState handles joining with queued tasks, and handles the exceptions that emerge from waiting on them.  AggregateExceptions are special-cased, and are flattened to eliminate extra levels that may have been added explicitly or implicitly; the code then checks to see whether all of the exceptions contained in the aggregate represent cancellation.  However, it fails to account for the possibility that there are no exceptions it contains, which could happen if the only exceptions thrown are themselves empty AggregateExceptions.  If that happens, the code makes some invalid assumptions that lead to a failed assert and then throwing an ObjectDisposedException.

The fix is just to check whether the flattened AggregateException is empty and to treat that not as cancellation but as a normal exception.
上级 c9d1fd60
......@@ -127,7 +127,7 @@ internal void QueryEnd(bool userInitiatedDispose)
// if all the exceptions were OCE(externalToken), then we will propagate only a single OCE(externalToken) below
// otherwise, we flatten the aggregate (because the WaitAll above already aggregated) and rethrow.
if (!allOCEsOnTrackedExternalCancellationToken)
if (!allOCEsOnTrackedExternalCancellationToken || flattenedAE.InnerExceptions.Count == 0)
throw flattenedAE; // Case #1
}
finally
......
......@@ -57,5 +57,20 @@ public static void ForAll_ArgumentNullException()
AssertExtensions.Throws<ArgumentNullException>("source", () => ((ParallelQuery<int>)null).ForAll(x => { }));
AssertExtensions.Throws<ArgumentNullException>("action", () => ParallelEnumerable.Range(0, 1).ForAll(null));
}
[Fact]
public static void ForAll_UserThrownAggregateException()
{
const int Count = 10;
try
{
new int[Count].AsParallel().Select<int, int>(i => throw new AggregateException()).ForAll(_ => { });
}
catch (AggregateException e)
{
// PLINQ internals flatten all AggregateExceptions.
Assert.Equal(0, e.InnerExceptions.Count);
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册