我有一个处理从数据库中提取的图像的应用程序。我需要并行处理各种图像,因此我使用.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有没有办法实现这个目标?
答案 0 :(得分:2)
这听起来非常适合TPL Dataflow ActionBlock
。您可以在开始时创建一个块。设置应同时处理的项目数(即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;