2012-04-04 4 views
4

작업 병렬 라이브러리를 사용하여 아래에 표시된대로 작업 체인을 설정하고 있지만 이해할 수없는 예외 처리 경험이 있습니다.잡힌 AggregateException에 예외가 없습니다.

나는 Parallel.ForEach를 사용하고 다음 메소드를 호출하는 Action을 호출한다. 이 Parallel.ForEach는 try ... catch (AggregateException)로 래핑되고 예외가 발생하면 Parallel 브랜치 중 하나에서와 마찬가지로 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); 
+1

여기서 '작업'을 사용하는 이유는 무엇입니까? 모든 메소드를 순차적으로 실행하지 않는 이유는 무엇입니까? – svick

+1

코드는 질문과 관련이없는 것 같습니다. 예외를 포착하고 처리하는 코드를 게시하십시오. –

+0

@svick - 전달 된 선택 작업이 병렬 처리됩니다. 또한 이들은 다른 상황에서 쉽게 재사용 될 수 있고 가능하다면 루트 작업으로 만들어 질 수있는 개별 빌딩 블록 작업입니다. – Ciaran

답변

6

은의 당신의 코드를 약간 단순화하자

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이 정상적으로 실행될 수 있고, throw하지 않으면 t3.Wait()이 예외를 throw하지 않음을 의미합니다.

해결 방법? 먼저 TaskContinuationOptions.NotOnFaulted을 사용하지 말고 대신 TaskContinuationOptions.OnlyOnRanToCompletion을 사용해야합니다. 그러나 그것은 "사라지는"예외의 문제를 해결하지 못합니다. 각 연속의 시작 부분에

  1. 전화 Wait()TaskContinuationOptions를 사용하지 않는 : 그를 해결하기 위해, 나는 두 가지 가능성을 참조하십시오. 즉, AggregateException에 포장 된 예외가 생길 수 있습니다.이 예외는 자체적으로 AggregateException으로 싸여 있으며 AggregateException 등으로 싸여 있습니다.이를 해결하려면 Flatten() 또는 Handle()을 사용할 수 있습니다.

  2. Task.WaitAll()을 사용하여 모든 작업을 기다리십시오. WaitAll()은 원래 예외가 포함될 AggregateException을 던지고 첫 번째 예외로 인해 취소 된 각 작업에 대해 TaskCanceledException을 던집니다.

+0

나는 Task.WaitAll 옵션에 갔다 - 가장 깨끗한 것 같았다. 이제 TaskCanceledExceptions뿐만 아니라 원하는 예외도 얻습니다. 많은 감사합니다. – Ciaran

관련 문제