使用TPL ActionBlock,是否可以在作业完成后添加新项目

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

我在我的应用程序中使用TPL ActionBlock来实现并行性。

我有一个将根据用户输入执行操作的应用程序。根据输入,有时该操作需要更多时间,而有时则不需要。

所以ActionBlock的真正目的是,每当有输入输入时,我都想先在UI中显示它(有一个窗口),然后在后台执行操作。因此,这个想法就像来自用户的任何东西一样,在用户界面中显示它并在后台并行执行操作。

现在,在UI(窗口)中,我有一个停止按钮来停止用户输入。每当我单击此功能时,用户将无法再输入任何内容。现在,我还要调用ActionBlock.Complete方法来检查队列/块是否完成。

所以这是我的疑问,

我正在按[停止]按钮作为单独的方法来调用ActionBlock.Complete(),它将等待作业完成,然后做一些工作并关闭UI。这真的是个好主意吗,还是我必须在构造函数内部或定义了ActionBlock.Complete()的地方调用ActionBlock

public void CheckJobQ()
{
    _jobs.Complete();
    _jobs.Completion.Wait();
}

并且_jobsActionBlock

var executionDataflowBlockOptions = new ExecutionDataflowBlockOptions()
{
    MaxDegreeOfParallelism = 100
};
_jobs = new ActionBlock<Tuple<Action<Element>, Element>>((job) =>
{
    job.Item1.Invoke(job.Item2);
}, executionDataflowBlockOptions);
c# asynchronous task-parallel-library tpl-dataflow
1个回答
-1
投票

所有数据流块都是线程安全的,因此调用:

_jobs.Complete();

...从ActionBlock的动作中是允许的,完全没问题。

另一方面,数据流块不是死锁安全的。因此,如果您在处理元素时等待块的完成:

_jobs.Completion.Wait();

...您可能已经把自己开了枪。该操作将永远不会完成,该块本身也不会完成。

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