我是线程新手,想做类似这个问题的事情:
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
答案 0 :(得分:12)
考虑到你描述的具体用法(观看文件),我建议你使用FileSystemWatcher确定何时有新文件,然后用线程池启动线程来处理文件,直到有没有更多要处理 - 此时线程退出。
这应该减少i / o(因为你不是经常轮询磁盘),减少CPU使用率(因为轮询磁盘的多个线程的常量循环将使用循环),并减少你运行的线程数任何一次(假设没有对文件系统进行不断的修改)。
您可能只想在主线程上打开和读取文件,并将数据传递给工作线程(如果可能),以将i / o限制为单个线程。
答案 1 :(得分:5)
我相信Parallels Extensions使这成为可能:
Parallel.Foreach
http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach.aspx http://blogs.msdn.com/pfxteam/
答案 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(),以便在恢复执行之前确保所有工作线程都已完成。