.NET中是否有用于长时间运行线程的线程调度程序?我们的场景是网络扫描仪。它连接到一组主机并使用低优先级后台线程并行扫描它们一段时间。我希望能够安排很多工作,但只能安排任何给定的10台或任意数量的同时扫描的主机。即使我创建自己的线程,使用带有许多回调和其他异步优点的ThreadPool,我最终也会耗尽资源。我应该看看MonoTorrent......如果我使用线程池,我可以将我的应用程序限制为足以让应用程序的其余部分顺利运行的某个数量吗?有没有我可以为n个长期存在的线程初始化的线程池?[编辑]似乎没有人注意到我对一些回复做了一些评论,所以我会在这里添加一些内容。给定目标主机的工作基本上是:对于每个测试探测目标(工作主要在SSH连接的目标端完成)将探测结果与预期结果进行比较(工作在引擎机器上完成)为主机准备结果有人可以吗解释为什么使用SmartThreadPool标志有负面作用?在.NET4中,您拥有集成的任务并行库。创建新任务(新线程抽象)时,您可以指定哪些任务是长时间运行的。我们在这方面有丰富的经验(从长远来看是几天而不是几分钟或几小时)。您也可以在.NET2中使用它,但它实际上是一个扩展,请在此处查看。在VS2010中,基于任务(而不是线程)调试并行应用程序得到了彻底改进。建议尽可能使用任务而不是原始线程。因为它允许您以更加面向对象的友好方式处理并行性。UPDATE未指定为长时间运行的任务将排队到线程池(或任何其他调度程序)。但是如果你指定一个任务运行很长时间,它只是创建一个单独的线程,不涉及任何线程池。CLR线程池不适合执行长时间运行的任务:它适用于执行创建线程几乎与执行方法本身一样昂贵的短任务。(或者至少有很大一部分时间花在执行该方法上。)正如您所见,.NET本身使用线程池线程,您不能为自己保留线程块,以免冒运行时风险。安排、限制和取消工作是另一回事。.NET工作队列没有其他内置线程池,因此您必须自己滚动(自己管理线程或BackgroundWorkers)或找到一个预先存在的线程池(AmiBar的SmartThreadPool看起来很有前途,但我还没有自己用过)。在您的特定情况下,最好的选择不是线程或线程池或后台工作者,而是框架提供的异步编程模型(BeginXXX,EndXXX)。使用异步模型的好处是,只要有数据要读取,TcpIp堆栈就会使用回调,并且回调会自动在线程池中的线程上运行。使用异步模型,您可以控制每个启动间隔的请求数,如果您愿意,您可以从低优先级线程启动所有请求,同时处理普通优先级线程上的请求,这意味着数据包将尽可能少地留在内部Tcp队列中的网络堆栈。异步客户端套接字示例-MSDNPS对于不进行大量计算但主要等待IO(网络、磁盘等)的多个并发和长时间运行的作业,更好的选择始终是使用回调机制而不是线程。我会创建自己的线程管理器。在下面的简单示例中,Queue用于保存等待线程,Dictionary用于保存活动线程,由ManagedThreadId键控。线程完成后,它会将自己从活动字典中删除,并通过回调启动另一个线程。您可以从UI更改最大运行线程限制,您可以将额外的信息传递给ThreadDone回调以监控性能等。如果线程失败,例如网络超时,可以将其重新插入到队列中。为Supervisor添加额外的控制方法,用于暂停、停止等。使用系统;使用System.Collections.Generic;使用系统线程;namespaceConsoleApplication1{publicdelegatevoidCallbackDelegate(intidArg);类程序{staticvoidMain(string[]args){newSupervisor().Run();Console.WriteLine("完成");控制台.ReadKey();}}classSupervisor{队列waitingThreads=newQueue();DictionaryactiveThreads=newDictionary();intmaxRunningThreads=10;对象储物柜=新对象();易变的布尔完成;publicvoidRun(){//排队一些线程for(inti=0;i0)){ThreadnextThread=waitingThreads.Dequeue();activeThreads.Add(nextThread.ManagedThreadId,nextThread);下一个线程。开始();Console.WriteLine("Thread"+nextThread.ManagedThreadId.ToString()+"launched");}done=(activeThreads.Count==0)&&(waitingThreads.Count==0);}}//每个线程完成后都会调用它voidThreadDone(intthreadIdArg){lock(locker){//从活动池中移除线程activeThreads.Remove(threadIdArg);}Console.WriteLine("线程"+threadIdArg.ToString()+"完成");启动等待线程();//这可以改为放在Run()结束时的等待循环中}}classWorker{CallbackDelegatecallback;publicWorker(CallbackDelegatecallbackArg){callback=callbackArg;}publicvoidDoWork(){System.Threading.Thread.Sleep(newRandom().Next(100,1000));回调(System.Threading.Thread.CurrentThread.ManagedThreadId);}}}使用内置的线程池,性能不错。或者,您可以在此处或扩展线程池中查看智能线程池实现,以限制工作线程的最大数量。以上是C#学习教程:.NET中是否有针对长时间运行线程的线程调度器?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
