0

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

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

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

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

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

例如“ManualResetEventSlim”的Wait()方法的描述是“阻塞当前线程直到当前ManualResetEventSlim被设置”。

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

4

2 回答 2

1

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

当您的应用程序启动时,您启动工作程序。它们都对并发集合,包进行操作。生产者搜索文件并放置对包的引用,消费者从包中获取引用并启动每个引用的任务。

当您想发出暂停信号时,只需暂停生产者即可。如果你这样做,如果袋子里什么都没有,消费者也会停止工作。如果这不是所需的行为,您可以简单地定义生产者的暂停也会清除包 - 先备份您的包,然后再清除它。这样所有正在运行的任务都将完成它们的工作,消费者不会开始新的任务,但它仍然可以运行并等待结果。

编辑:

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

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

于 2013-08-20T15:26:30.433 回答
0

当然,您可以为此使用 TPL。并且也可能是响应式扩展和 LINQ,以简化分组和暂停/恢复线程工作。

如果您对每个文件只有一个简短的工作,那么最好不要通过取消来干扰处理程序函数。您可以暂停工作人员排队。

我想象这样的事情:

  • 您的目录扫描线程将找到的文件放入可观察的集合中。
  • 消费者线程订阅集合更改并获取/删除文件并将它们分配给工作人员。
于 2013-08-20T15:32:51.843 回答