gpt4 book ai didi

c# - 我捕获的 AggregateException 没有我期望的异常

转载 作者:太空狗 更新时间:2023-10-30 00:55:18 24 4
gpt4 key购买 nike

我正在使用任务并行库来设置任务链,如下所示,但我得到了一个我不理解的奇怪的异常处理体验。

我使用 Parallel.ForEach 并调用一个 Action,其中包括对以下方法的调用。这个 Parallel.ForEach 被包裹在一个 try...catch(AggregateException) 中,当发生异常时——就像在并行分支之一中发生的那样——一个 SchemaValidation 异常,然后我希望在 AggregateException 中看到它。

但是,我得到的是“任务已取消”- TaskCanceledException。我的 SchemaValidationException 哪里去了?

        private static void ProcessChunk(Task<ISelectedChunk> selectionTask, 
IRepository repository,
IIdentifiedExtractChunk identifiedExtractChunk,
IBatchRunConfiguration batchRunConfiguration,
IBatchRun batchRun,
ILog log,
IAuthenticationCertificate authenticationCertificate,
IFileSystem fileSystem,
long batchRunRid)
{
var transformationTask = selectionTask.ContinueWith(TransformationFunction.Transformation(identifiedExtractChunk, batchRunConfiguration, batchRun),
TaskContinuationOptions.NotOnFaulted);

var schemaValidationTask = transformationTask.ContinueWith(SchemaValidationFunction.SchemaValidationTask(batchRunConfiguration),
TaskContinuationOptions.NotOnFaulted);

var compressTask = schemaValidationTask.ContinueWith(CompressFunction.CompressTask(identifiedExtractChunk),
TaskContinuationOptions.NotOnFaulted);

var encryptTask = compressTask.ContinueWith(EncryptionFunction.EncryptTask(authenticationCertificate),
TaskContinuationOptions.NotOnFaulted);

var fileGenerationTask = encryptTask.ContinueWith(FileGenerationFunction.FileGenerationTask(identifiedExtractChunk, batchRunConfiguration, fileSystem),
TaskContinuationOptions.NotOnFaulted);
// Take the time before we start the processing
DateTime startBatchItemProcessing = DateTime.Now;

// Start with the Selection Task
selectionTask.Start();

// And wait on the last task in the chain
fileGenerationTask.Wait();

// Take the time at the end of the processing
DateTime endBatchItemProcessing = DateTime.Now;

// Record all the relevant information and add it to the collection
IBatchChunkProcessed batchChunkProcessed = GetBatchItemProcessed(identifiedExtractChunk, batchRunRid, fileGenerationTask.Result, transformationTask.Result.Item2, startBatchItemProcessing, endBatchItemProcessing);
BatchItemsProcessed.Add(batchChunkProcessed);

最佳答案

让我们稍微简化一下您的代码:

var t1 = Task.Factory.StartNew(a1);
var t2 = t1.ContinueWith(a2, TaskContinuationOptions.NotOnFaulted);
var t3 = t2.ContinueWith(a3, TaskContinuationOptions.NotOnFaulted);

t3.Wait();

现在假设 a1 抛出异常。 t1 发生故障 (t1.Status == TaskStatus.Faulted)。因此,t2 无法运行(因为 NotOnFaulted),因此它将被取消。但这不是您可能期望的:t2 不会出错,它会被取消 (t2.Status == TaskStatus.Canceled)。但这意味着t3可以正常运行,如果不抛出,t3.Wait()也不会抛出任何异常。

如何解决这个问题?首先,您可能不应该使用 TaskContinuationOptions.NotOnFaulted,而应该使用 TaskContinuationOptions.OnlyOnRanToCompletion。但这并不能解决异常“消失”的问题。为了解决这个问题,我看到了两种可能性:

  1. 在每个延续开始时调用 Wait() 并且不使用任何 TaskContinuationOptions。这意味着你可能会得到一些包裹在 AggregateException 中的异常,它本身包裹在 AggregateException 中,它又包裹在另一个 AggregateException 中,等等。要解决这个,你可以使用 Flatten()Handle() .

  2. 等待所有任务,使用Task.WaitAll() . WaitAll() 将抛出一个 AggregateException,其中包含原始异常以及因第一个异常而被取消的每个任务的 TaskCanceledException .

关于c# - 我捕获的 AggregateException 没有我期望的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10008964/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com