ActionBlock B从不接收TransformBlock A返回的项目

问题描述 投票:1回答:1

我的C#/ WPF应用程序中的TPL数据流网格存在问题。第一个输入项(称为“作业”)始终贯穿整个链,直到最后一个TPL块。但是,即使日志语句清楚地表明已成功从块#3中返回它们,其余的作业也从未到达最后一个块(#4)。

这里是网格。设置一次并存储在我的View-Model类的私有成员中。

// 1. _meshStartBlock:  On UI thread.   This block always works fine.

_meshStartBlock = new TransformBlock<Job, Job>(job =>
{
    Jobs.Add(job);
    Fire(_scanCapturedTrigger, job);  // Notify sstate machine.
    Log.Debug("Started: " + job.Name);
    return job;
},
new ExecutionDataflowBlockOptions
{
    CancellationToken = TokenSource.Token,
    TaskScheduler = UiTaskScheduler   // Run on UI thread (because it edits
                                      // our ObservableCollection)
});

// 2. createBlock:  This block also always works fine.

var createBlock = new TransformBlock<Job, Job>(job =>
{
    job.CreateScan();          // Saves some disk files
    job.CreateThumbnail(true); // Creates and saves a thumbnail image.
    Log.Debug("Created: " + job.Name);
    return job;
},
new ExecutionDataflowBlockOptions
{ CancellationToken = TokenSource.Token, MaxDegreeOfParallelism = 1 });


// 3. processBlock - do heavy work in parallel
// This block succeeds for all 3 jobs but 2nd and 3rd returned jobs never
// reach the next block.

var processBlock = new TransformBlock<Job, Job>(job =>
{
    try
    {
        Log.Debug("Processing: " + job.Name);
        job.AlignImages();            // heavy image processing
        job.Generate3d();             // heavy 3d math
        job.FindShapes();             // more heavy match
        job.GetContext().Scan.Save(); // save disk files
        Log.Debug("Processing succeeded: " + job.Name
    }
    catch (Exception e)
    {
        Log.Error("Processing failed: " + job.Name);
    }

    // *** THIS LOG STATEMENT SHOWS UP FOR ALL 3 JOBS ***

    Log.Debug("Leaving process block: " + job.Name);

    return job;
},
new ExecutionDataflowBlockOptions
{ CancellationToken = TokenSource.Token, MaxDegreeOfParallelism = 3 });


// 4. doneBlock: Cleans up.
// Since we schedule this on the UI thread it should not be heavy.

var doneBlock = new ActionBlock<Job>(job =>
{
    // *** ONLY REACHED BY JOB 1 ***  

    Log.Debug("Done: " + job.Name);
    Fire(Trigger.ScanProcessed);    // Notify State Machine
},
new ExecutionDataflowBlockOptions
{ CancellationToken = TokenSource.Token,  TaskScheduler = UiTaskScheduler });

// Set up the mesh.  Link the blocks together to form a chain.

_meshStartBlock.LinkTo(createBlock);
createBlock.LinkTo(processBlock);
processBlock.LinkTo(doneBlock);

return _meshStartBlock;

这是我得到的日志输出

Started: Job1
Created: Job1
Started: Job2
Processing: Job1
Created: Job2
Processing: Job2
Started: Job3
Created: Job3
Processing: Job3
Processing succeeded: Job1
Leaving process block: Job1
Done: Job1
Processing succeeded: Job2
Leaving process block: Job2
Processing succeeded: Job3
Leaving process block: Job3

“调试”窗口在处理或转储任何类型的错误消息期间均不会报告任何异常。

我应该注意,我被迫在Release版本中运行它。如果我运行调试版本,则该过程块将花费数小时。而且从不调用CancellationToken

任何TPL-Dataflow专家都可以告诉我如何诊断Job2和Job3吗?无论如何,我可以得到TPL Dataflow来告诉我乔布斯发生了什么吗?

我的C#/ WPF应用程序中的TPL数据流网格存在问题。第一个输入项(称为“作业”)始终贯穿整个链,直到最后一个TPL块。但是剩下的工作...

c# task-parallel-library tpl-dataflow
1个回答
0
投票

这可能有助于将错误处理程序附加到块上,以便在异常发生时立即记录它们。这是一个简单的通用错误处理程序的示例:

© www.soinside.com 2019 - 2024. All rights reserved.