C#中的“任务包”概念,排队,暂停,取消逻辑任务

时间:2013-08-20 15:05:09

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

我正在开发的应用程序是这样组成的: 生产者任务扫描文件系统中的文本文件并将其引用放入包中。 许多消费者任务同时从包中取出文件引用并读取文件(并对其内容做一些简短的工作)

我必须能够暂停并恢复整个过程。

我尝试过使用TPL,为每个文件ref创建一个任务,因为它们被放入包中(在这种情况下,包只是一个概念,生产者直接创建消费者任务,因为它找到文件)但这种方式我无法控制我创建的任务,我不能(或者我不知道如何)暂停它们。我可以编写一些代码来暂停当前正在执行任务的线程,但这会破坏使用逻辑任务而不是手动创建线程的意义不是吗?我希望像“已分配到物理线程的任务可以完成但等待逻辑任务不应该在恢复命令之前启动”

我怎么能做到这一点?它可以用TPL完成还是我应该使用其他东西?

修改 你的答案都是有效的,但我的主要疑问仍然没有答案。我们正在谈论任务,如果我使用TPL我的生产者,我的许多消费者将是任务(对吗?)而不是线程(好吧,好的,执行任务将被映射到线程上)。我发现的每个同步机制(如评论“ManualResetEventSlim”中提出的那个)都在线程级别工作。

E.g。 “ManualResetEventSlim”的Wait()方法的描述是“阻止当前线程,直到设置当前的ManualResetEventSlim。”

我对任务的了解纯粹是学术性的,我不知道事物在“现实世界”中是如何运作的,但我认为我需要一种方法来协调(等待/信号/ ...)任务级别或事情可能会变得奇怪......就像...两个任务可能映射在同一个线程上,但一个应该发出信号,另一个正在等待然后死锁。我有点困惑。这就是我问我的应用程序是否可以使用TPL而不是旧式简单线程的原因。

2 个答案:

答案 0 :(得分:1)

是的,你可以这样做。首先,你有一个主线程,你的应用程序。你有两个工人,由线程代表。第一个工人是生产者,第二个工人是消费者。

当您的应用程序启动时,您启动工作人员。它们都在并发集合上运行。生产者搜索文件并将引用放入行李中,消费者从行李中获取引用,并按引用启动任务。

当您想要发出暂停信号时,只需暂停生产者即可。如果这样做,如果包里没有任何东西,消费者也会停止工作。如果这不是一个理想的行为,你可以简单地定义生产者的暂停还清除包 - 先备份你的包,然后清除它。这样,所有正在运行的任务都将完成其工作,消费者将无法启动新任务,但它仍然可以运行并等待结果。

修改

根据您的修改。我不知道如何以你想要的方式实现它,但尽管尝试使用新技术很好,但不要让你的思绪蒙上阴影。使用ThreadPool也是件好事。启动应用程序需要更多时间,但一旦运行,消耗将更快,因为您已经准备好了工作人员。

这不是一个坏主意,您可以指定最大数量的工人。如果为包中的每个项创建一个任务,它将更耗费内存,因为您仍将分配和释放内存。这不会发生在ThreadPool

答案 1 :(得分:0)

当然,您可以使用TPL。也可以是reactive extensions和LINQ来简化分组,pausing/resuming线程可以工作。

如果您在每个文件上只有一个简短的工作,那么不要通过取消来打扰处理程序功能。您可以暂停对工作人员进行排队。

我想象这样的事情:

  • 您的目录扫描程序线程将找到的文件放入可观察的集合中。
  • 消费者线程订阅集合更改并获取/删除文件并将其分配给工作人员。