“;任务袋”;C#中的概念,将逻辑任务排队、暂停、取消
本文关键字:任务 暂停 取消 排队 | 更新日期: 2023-09-27 18:28:30
我正在开发的应用程序是这样组成的:生产者任务扫描文件系统中的文本文件,并将它们的引用放在包中。许多使用者任务同时从包中获取文件引用并读取文件(并对其内容进行一些简短的处理)
我必须能够暂停并恢复整个过程。
我尝试过使用TPL,在每个文件引用放入包中时为它们创建一个任务(在这种情况下,包只是一个概念,生产者在查找文件时直接创建消费者任务),但这样我就无法控制我创建的任务,我无法(或不知道如何)暂停它们。我可以写一些代码来挂起当前执行任务的线程,但这会破坏处理逻辑任务而不是手动创建线程的意义,不是吗?我想要类似"已经分配给物理线程的任务可以完成,但等待的逻辑任务不应该在恢复命令之前启动"
我怎样才能做到这一点?它可以用TPL完成吗?还是我应该用其他东西?
编辑:你的回答都是正确的,但我的主要疑问仍未得到解答。我们谈论的是任务,如果我使用TPL,我的生产者和消费者将是任务(对吧?)而不是线程(好吧,在执行的时候,任务将映射到线程上)。我发现的每一种同步机制(比如评论"ManualResetEventSlim"中提出的机制)都在线程级别工作。
例如,"ManualResetEventSlim"的Wait()方法的描述是"阻止当前线程,直到设置了当前ManualResetAventSlim。"
我对任务的了解纯粹是学术性的,我不知道"现实世界"中的事情是如何运作的,但对我来说,我需要一种在任务级别协调(等待/信号/…)任务的方法,否则事情可能会变得奇怪,这似乎是合乎逻辑的。。。喜欢两个任务可能映射在同一个线程上,但其中一个应该向正在等待的另一个发出信号,然后死锁。我有点困惑。这就是为什么我问我的应用程序是否可以使用TPL而不是老式的简单线程。
是的,你可以做到。首先,你有一个主线程,你的应用程序。这里有两个工人,用线程表示。第一个工人是生产者,第二个工人是消费者。
当你的应用程序启动时,你就启动了工作者。它们都对并发集合bag进行操作。生产者搜索文件并将引用放在包中,消费者从包中获取引用并根据每个引用启动任务。
当您想发出暂停信号时,只需暂停生产者。若你们这样做,若袋子里什么都并没有,消费者也会停止工作。如果这不是一种理想的行为,你可以简单地定义生产者的暂停也会清空袋子-先备份你的袋子,然后清空它。这样,所有正在运行的任务都会完成任务,消费者不会开始新的任务,但它仍然可以运行并等待结果。
编辑:
基于您的编辑。我不知道如何以你想要的方式实现它,但尽管尝试使用新技术很好,但不要让你的头脑蒙上阴影。使用ThreadPool
也是一件好事。启动应用程序需要更多的时间,但一旦运行,消耗速度就会更快,因为您已经准备好了工作人员。
这不是一个坏主意,你可以指定一个最大数量的工人。如果您为包中的每个项目创建一个任务,它将更消耗内存,因为您仍将分配和释放内存。ThreadPool
不会发生这种情况。
当然可以使用TPL。也可以是响应式扩展和LINQ,以简化分组和暂停/恢复线程工作。
如果您对每个文件只有一个简短的工作,那么最好不要用取消来干扰处理程序函数。你可以暂停工人排队。
我想是这样的:
- 目录扫描程序线程将找到的文件放入一个可观察的集合中
- 使用者线程订阅集合更改并获取/删除文件并将其分配给工作者