2

ノンブロッキング並列処理方式で実行する必要がある次のワークフローがあります。メソッドをすぐに返したいDoStuff()ので、タスク並列ライブラリを使用しています

DoStuff():
  Do some setup
  Parse an Excel file

  then for each row
   Fill Template with parsed values
   Convert filled template to Pdf
   Convert pdf to Tiff

  when all row processing has completed Create Summary Text File

  when summary text file has completed, Finalize

すぐに戻りたいので、「すべての行の処理が完了したとき」の手順に少しつまずきました。次のことは大まかに私がすべきことですか?

public Task<ProcessingResult> DoStuff() {
    return new Task<SetupResult>(SetUp)
        .ContinueWith(ParseExcel, TaskContinuationOptions.OnlyOnRanToCompletion)
        .ContinueWith(excelProcessing => {
            var templateProcessing = excelProcessing.Result.RowParsing
                .Select(template =>
                  new Task<TemplateFillingResult>(()=>FillTemplate)
                       .ContinueWith(ConvertToPdf, TaskContinuationOptions.OnlyOnRanToCompletion)
                       .ContinueWith(ConvertToTiff, TaskContinuationOptions.OnlyOnRanToCompletion)
                ).ToArray()

            //-------------------------------------------------------------
            // This is the part that seems wierd
            //-------------------------------------------------------------
            Task.Factory.ContinueWhenAll(templateTasks, t=> { }).Wait();
            return new TemplatesProcessingResult(templateProcessing);
        }, TaskContinuationOptions.OnlyOnRanToCompletion)
        .ContinueWith(CreateSummaryFile, TaskContinuationOptions.OnlyOnRanToCompletion)
        .ContinueWith(FinalizeProcessing, TaskContinuationOptions.OnlyOnRanToCompletion);
4

1 に答える 1

6

元のイベントの続きとしてこれらすべてのコンポーネントを接続しようとしているため、混乱していると思います。これらの呼び出しをすべて継続するやむを得ない理由がない場合、これはすべて、単一のバックグラウンドスレッド(タスク)で簡単に実行できます。

var task = Task.Factory.StartNew(() =>
   {
        // setup
        // var stuff = ParseFile()

        // Executes elements in parallel and blocks this thread until all have completed, else bubbles the exception up
        var transformations = excelProcessing.Result.RowParsing.AsParallel().Select(x =>
           {
                FillTemplate(x);
           }).ToArray();

        // create summary text file

        // Finalize

        return processingResult;
   });

基本的に、これらすべてを1つのスレッドで実行でき、心配する必要はありません。これらすべてのステップを継続としてマークアップすることは、あなたがしなければならないことに対してかなり複雑です。

次に、呼び出し元のコードは、その人のプロパティをブロックするだけResultで、非同期呼び出しの結果を取得できます。

  try
  {
      var result = task.Result;
  }
  catch(AggregateException e)
  {
      e.Flatten().Handle(ex => 
        {
             // Do Stuff, return true to indicate handled
        });
  }

ただし、認識しておく必要があるのは例外です。これがファイアアンドフォーゲットタスクになる場合、例外がある場合、それは完全にバブルし、プロセスを強制終了する可能性があります。

于 2012-04-16T19:14:09.953 に答える