使用多线程进行循环

时间:2010-04-29 15:23:17

标签: c# multithreading .net-3.5

我是线程新手,想做类似这个问题的事情:

Speed up loop using multithreading in C# (Question)

然而,我不确定这个解决方案对我来说是否是最好的解决方案,因为我希望它们继续运行并且永远不会完成。 (我也使用.net 3.5而不是2.0。)

我想做这样的事情:

foreach (Agent agent in AgentList)
{
    // I want to start a new thread for each of these
    agent.DoProcessLoop();
}

---

public void DoProcessLoop()
{
    while (true)
    {
        // do the processing

        // this is things like check folder for new files, update database
        // if new files found
    }
}

ThreadPool是最好的解决方案还是有更适合这种情况的东西?

更新:感谢您的所有好消息!我以为我会更详细地解释用例。许多代理可以将文件上载到文件夹。每个代理都有自己的文件夹,可以将资源上传到(csv文件,图像,pdf)。我们的服务(它意味着是在他们上传资产的服务器上运行的Windows服务,请放心,我将很快回来关于Windows服务的问题:))如果有任何新资产,将继续检查每个代理的文件夹,如果有,数据库将被更新,并为其中一些创建静态html页面。因为他们可能需要一段时间来上传所有内容,我们希望他们能够立即看到他们上传的更改,我们认为每个代理的线程都是个好主意,因为没有代理人需要等待其他人来完成(我们有多个处理器,所以想要使用它们的全部容量)。希望这能解释它!

谢谢,

Annelie

7 个答案:

答案 0 :(得分:12)

考虑到你描述的具体用法(观看文件),我建议你使用FileSystemWatcher确定何时有新文件,然后用线程池启动线程来处理文件,直到有没有更多要处理 - 此时线程退出。

这应该减少i / o(因为你不是经常轮询磁盘),减少CPU使用率(因为轮询磁盘的多个线程的常量循环将使用循环),并减少你运行的线程数任何一次(假设没有对文件系统进行不断的修改)。

您可能只想在主线程上打开和读取文件,并将数据传递给工作线程(如果可能),以将i / o限制为单个线程。

答案 1 :(得分:5)

答案 2 :(得分:2)

ThreadPool的一个问题是,如果池恰好小于您希望拥有的代理程序数,那么您尝试稍后启动的代理可能永远不会执行。某些任务可能永远不会开始执行,并且您可能会使应用程序域中使用线程池的其他所有内容都饿死。你最好不要沿着这条路走下去。

答案 3 :(得分:2)

你肯定想要将ThreadPool用于此目的。 ThreadPool线程不应该用于长时间运行的任务(“无限”计数作为长时间运行),因为这显然会占用要共享的资源。

对于您的应用程序,最好创建一个线程(不是来自ThreadPool的)并在该线程中执行您的while循环,在其中迭代您的代理收集并执行每个处理。在while循环中,您还应该使用Thread.Sleep调用,这样您就不会最大化处理器(有更好的方法可以定期执行代码,但Thread.Sleep可以用于您的目的)。< / p>

最后,您需要在程序终止时为while循环添加一些方法来退出。

更新:最后,多线程会自动加速运行缓慢的代码。九个女人在一个月内不能生孩子。

答案 4 :(得分:1)

当您期望线程相当频繁地进入和不存在时,线程池很有用,而不是预定义的设置线程数。

答案 5 :(得分:0)

嗯..正如Ragoczy所指出的,最好使用FileSystemWatcher来监控文件。但是,由于您有其他操作,您可以考虑多线程。

但要注意,无论你拥有多少个处理器,它的容量都有限制。您可能不希望创建与并发用户数一样多的线程,原因很简单,因为您的代理数量可能会增加。

答案 6 :(得分:-1)

在升级到.NET 4之前,ThreadPool可能是您的最佳选择。您可能还希望使用Semaphore和AutoResetEvent来控制并发线程的数量。如果你在谈论长时间运行的工作,那么启动和管理你自己的线程的开销很低,而且解决方案更优雅。这将允许您使用WorkerThread.Join(),以便在恢复执行之前确保所有工作线程都已完成。