【问题标题】:.NET TPL Start a task after one ends indefinitely.NET TPL 无限期结束后启动任务
【发布时间】:2015-04-30 02:47:22
【问题描述】:

我有一个处理从数据库中提取的图像的应用程序。我需要并行处理各种图像,因此我将 .NET TPL 与 Tasks 一起使用。

我的应用程序是 C# 中的 Winforms 应用程序。我只能选择启动多少个进程和一个“开始”按钮。我现在的做法是这样的:

private Action getBusinessAction(int numProcess) {
    return () =>
    {
        try {
            while (true) {
                (new BusinessClass()).doSomeProcess(numProcess);
                tokenCancelacion.ThrowIfCancellationRequested();
            }
        }
        catch (OperationCanceledException ex) {
            Console.WriteLine("Cancelled process");
        }
    };
}

...

for (int cnt = 0; cnt < NUM_OF_MAX_PROCESS; cnt++) {
    Task.Factory.StartNew(getBusinessAction(cnt + 1), tokenCancelacion);
}

在这种情况下,如果我选择 8 作为进程数,它将启动 8 个正在运行的任务,直到应用程序关闭。但我认为更好的方法是启动一些调用doSomeProcess 方法的任务,然后完成。但是当任务完成时,我想启动相同的任务或启动执行相同任务的新实例,以便始终并行运行该数量的进程。 TPL 中有没有办法实现这一点?

【问题讨论】:

  • 任务如何完成?你在那里有一个无限循环。
  • 如果对你有用的话,可能是一些重载的 Task.WaitAny 方法msdn.microsoft.com/library/dd270672(v=vs.110).aspx
  • @SriramSakthivel 我已经修改了一点,而不是 while(true) 我在静态类中有一个静态 bool 属性,我也有: tokenCancelacion.ThrowIfCancellationRequested();停止执行。当我按下按钮停止执行任务时,该布尔变量会发生变化,因此while循环会消失。

标签: c# .net task-parallel-library task


【解决方案1】:

这听起来很适合TPL DataflowActionBlock。您在开始时创建一个块。设置它应该同时处理多少个项目(即 8 个)并将项目发布到其中:

var block = new ActionBlock<Image>(
    image => ProcessImage(image), 
    new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 8});

foreach (var image in GetImages())
{
    block.Post(image);
}

这将负责在需要时创建多达 8 个任务,当它们不再需要时,数量会减少。

完成后,您应该发出块完成的信号并等待它完成:

block.Complete();
await block.Completion;

【讨论】:

  • 听起来不错。我唯一需要的是,当 rhose 8 任务完成后,我需要自动启动另外 8 个任务,无需用户干预。或者,如果只有其中一项任务结束,则开始一项新的任务,执行相同的操作。目的是让 X 进程始终处于活动状态,处理图像。现在这就是为什么我在我的任务中使用无限循环的原因,但我希望有 8 个进程结束并开始新的进程,而不是有相同的 8 个进程,其中有无限循环
  • @OscarCalderon 这正是ActionBlock 所做的。您当然可以尝试自己实现它,但我建议您改用它。
  • 好的,我会试试,然后告诉你,谢谢。
  • 只有一件事:在您的代码中,有一个名为 GetImages 的方法,它返回图像或类似的东西,并将其作为参数传递给 ProcessImage 方法。就我而言,我不想返回任何东西,而且我的方法没有收到任何参数超过线程号,这仅用于演示目的。在我的代码中,方法本身得到了他自己的图像。如何适配TPL Dataflow?
  • @OscarCalderon 这只是一个例子。重点是将要处理的项目泵入ActionBlock。由于您尚未基于 TPL 数据流,因此您需要对其进行更改以适应它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-26
  • 2015-11-22
  • 2016-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多