我的目标是编写一个程序,根据给定的用户输入处理任意数量的任务。
在这种情况下,假设任务数量为1000。
现在,我希望能够生成动态数量的线程并逐个开始处理任务。
我认为我需要使用“同步”方法,而不是“异步”方法,以便在一个任务出现问题的情况下,我不希望它减慢其余任务的完成速度。
我将用什么方法来完成上述操作?信号灯?线程池?如何确保线程不会尝试启动已由另一个线程处理的任务? “锁定”会处理这个吗?
我们将非常感谢代码示例和/或指向正确方向的网站链接。
编辑:MSDN Fibonacci示例的问题是waitall方法最多只能处理64次等待。由于1000项任务,我需要更多。如何解决这种情况而不会造成死锁?
答案 0 :(得分:10)
这些任务是否独立?如果是这样,你基本上需要一个生产者/消费者队列或一个自定义线程池,它们对同一个东西实际上是不同的视图。您需要能够将任务放入队列中,并且有多个线程能够从该队列中读取。
我在MiscUtil中有一个自定义线程池,或者threading tutorial中有一个简单的(由于年龄而非通用)生产者/消费者队列(大约在this page的一半)。
如果这些任务合理地长时间运行,我就不会使用系统线程池 - 它会产生比你想要的更多的线程。如果您使用的是.NET 4.0 beta 1,则可以使用Parallel Extensions。
我不太确定你对WaitAll
的评论......当你完成所有事情时,你是否想要解决?在生产者/消费者队列的情况下,这可能涉及在队列中有某种“停止”条目(例如,消费线程理解为意味着“退出”的空引用),然后添加“WaitUntilEmpty”方法(应该相当容易实现)。请注意,您不需要等到最后一项处理,因为它们都是停止信号......当队列清空时,所有实际工作项肯定会无论如何已被处理。
答案 1 :(得分:2)
您可能希望使用ThreadPool来管理它。
我建议您阅读MSDN on How to use the ThreadPool in C#。它涵盖了很多方面,包括解雇任务和简单同步。
Using Threading in C#是主要部分,将涵盖其他选项。
如果你碰巧使用的是VS 2010测试版,并且目标是.NET 4,那么Task Parallel Library是一个非常好的选择 - 它简化了其中一些模式。
答案 2 :(得分:1)
你还不能使用它,但.NET 4中的新Task类对于这种情况是理想的 在那之前,ThreadPool是你最好的选择。它具有(非常)有限的负载平衡形式。请注意,如果您尝试启动1000个线程,则可能会出现“内存不足”异常。 ThreadPool将轻松处理它。
如果时间安排在主线程中可以容忍Sleep(1)循环,则可以使用简单的(Interlocked)计数器处理同步问题。 ThreadPool缺少一种更方便的方法。
答案 3 :(得分:0)
避免任务的一个简单策略是通过两个或多个线程获得同步(例如,使用mutext)向量。
答案 4 :(得分:0)
也许您可以使用BackgroundWorker
课程。它在线程池之上创建了一个很好的抽象。如果要设置许多类似的作业,甚至可以将其子类化。
答案 5 :(得分:0)
正如已经提到的,.NET 4具有出色的任务并行库。但是你可以在.NET 3.5中使用它的June 2008 CTP就好了。我自己一直在为一些业余爱好项目做这个,但如果这是一个商业项目,你应该检查是否存在法律问题。