当前位置: 首页 > 编程语言 > C#

c#Threadpool-限制线程数分享

时间:2023-04-10 18:23:47 C#

c#Threadpool-限制线程数我正在开发一个控制台应用程序,我想使用Threadpool来执行网络下载。这是一些假代码。for(intloop=0;loop<100;loop++){ThreadPool.QueueUserWorkItem(newWaitCallback(GetPage),pageList[loop]);}snipprivatestaticvoidGetPage(objecto){//获取页面}如何阻止我代码启动超过两个(或十个或其他)同时线程?我试过ThreadPool.SetMaxThreads(1,0);ThreadPool.SetMinThreads(1,0);但它们似乎没有任何作用。我会使用Parallel.For并相应地设置MaxDegreeOfParallelism。Parallel.For(0,1000,newParallelOptions{MaxDegreeOfParallelism=10},i=>{GetPage(pageList[i]);});只需反转以下代码:ThreadPool.SetMaxThreads(1,0);ThreadPool.SetMinThreads(1,0);到:ThreadPool.SetMinThreads(1,0);ThreadPool.SetMaxThreads(1,0);您不能将MaxThread设置为小于MinThread就个人而言,我会使用SmartThreadPool并单独保留ThreadPool。但是,这可能是您想要的:链接中包含的C#线程池限制线程代码(归功于原作者,而不是我)System.Threading.SemaphoreS=newSystem.Threading.Semaphore(3,3);try{//轮到你了(递减)S.WaitOne();//做你的事}finally{//释放以便其他人可以去(增量)S.Release();}Description您可以使用ThreadPool.SetMaxThreads方法来执行此操作。但是对于WebRequest使用ThreadPool有一些问题。例如,阅读(ThreadPool或HttpWebRequest中的错误?)示例ThreadPool.SetMaxThreads(2,2);编辑就个人而言,我会使用LinqAsParallel。有关详细信息,请参阅ThreadPool.SetMaxThreads的参数。第一个参数是工作线程数,第二个参数是异步线程数,就是你说的那个。在文档的更下方,它说:您不能将工作线程或I/O完成线程的数量设置为小于计算机中处理器数量的数字。听起来你正试图将ThreadPool用于它不打算用于的事情。如果你想限制下载,创建一个类来为你管理这个,因为ThreadPool不一定是你问题的完整解决方案。我建议在ThreadPool中启动两个线程并等待回调的类。其中一个线程在接收到完成回调时将新线程排队。如果你收紧到.Net2.0,你可以使用以下技术:知道你将一个任务排入线程池的事实,它将创建一个新线程(当然,如果没有空闲线程),你将等待直到有一个空闲的才这样做溃败。为此,使用了BlockingCounter类(如下所述),一旦达到限制,它就会等待增加,直到有人(另一个线程)减少它。然后它进入“关闭”状态,这意味着不会进行新的增量并等待完成。下面的示例最多显示4个任务,总共10个。类程序{staticints_numCurrentThreads=0;静态随机s_rnd=newRandom();staticvoidMain(string[]args){intmaxParallelTask??s=4;inttotalTask??s=10;使用(BlockingCounterblockingCounter=newBlockingCounter(maxParallelTask??s)){for(inti=1;i{try{ThreadProc(obj);}catch(Exceptionex){Console.Error.WriteLine("任务{0}失败:{1}",obj,ex.Message);}finally{//这里也可能出现异常,//但正确的错误处理不是本示例的目标blockingCounter.WaitableDecrement();}},i)){blockingCounter.WaitableDecrement();Console.Error.WriteLine("提交任务{0}执行失败。",i);}}Console.WriteLine("等待完成......");blockingCounter.CloseAndWait(30000);}Console.WriteLine("工作完成!");控制台.ReadKey();}staticvoidThreadProc(objectobj){inttaskNumber=(int)obj;intnumThreads=Interlocked.Increment(refs_numCurrentThreads);Console.WriteLine("任务{0}started.Total:{1}",taskNumber,numThreads);intsleepTime=s_rnd.Next(0,5);Thread.Sleep(sleepTime*1000);Console.WriteLine("任务{0}完成。",taskNumber);Interlocked.Decrement(refs_numCurrentThreads);}它使用BlockingCounter类,它基于此处发布的MarcGravell的SizeQueue,但没有计数器而不是队列当您完成对新线程的排队时,调用Close()方法并等待完成。公共类BlockingCounter:IDisposable{privateintm_Count;私有对象m_counterLock=newobject();私人布尔m_isClosed=假;私人挥发性布尔m_isDisposed=假;私人诠释m_MaxSize=0;privateManualResetEventm_Finished=newManualResetEvent(false);publicBlockingCounter(intmaxSize=0){if(maxSize0&&m_Count>=m_MaxSize){CheckClosedOrDisposed();if(!Monitor.Wait(m_counterLock,ti??meoutMs))thrownewTimeoutException("未能等待计数器递减。");}CheckClosedOrDisposed();m_计数++;如果(m_Count==1){Monitor.PulseAll(m_counterLock);}}}publicvoidWaitableDecrement(inttimeoutMs=Timeout.Infinite){lock(m_counterLock){try{while(m_Count==0){CheckClosedOrDisposed();if(!Monitor.Wait(m_counterLock,ti??meoutMs))thrownewTimeoutException("未能等待计数器递增。");}CheckDisposed();m_Count--;如果(m_MaxSize==0||m_Count==m_MaxSize-1)Monitor.PulseAll(m_counterLock);}finally{if(m_isClosed&&m_Count==0)m_Finished.Set();}}}voidCheckClosedOrDisposed(){if(m_isClosed)thrownewException("计数器已关闭");CheckDisposed();}voidCheckDisposed(){if(m_isDisposed)thrownewObjectDisposedException("计数器已被处理。");}publicvoidClose(){lock(m_counterLock){CheckDisposed();m_isClosed=真;Monitor.PulseAll(m_counterLock);}}publicboolWaitForFinish(inttimeoutMs=Timeout.Infinite){CheckDisposed();锁(m_counterLock){如果(m_Count==0)返回真;}返回m_Finished.WaitOne(timeoutMs);}publicvoidCloseAndWait(inttimeoutMs=Timeout.Infinite){Close();等待完成(超时时间);}publicvoidDispose(){if(!m_isDisposed){m_isDisposed=true;lock(m_counterLock){//唤醒所有等待的线程,让它们知道对象//已处理,没有什么可以再等待了Monitor.PulseAll(m_counterLock);}m_Finished.C失去();结果会是这样的:以上就是C#学习教程:c#Threadpool-限制线程数共享所有内容,如果对大家有用需要详细了解C#学习教程,希望大家多多关注提交任务1提交任务2提交任务3提交任务4提交任务5任务1开始了。总计:1任务1已完成。任务3开始。总计:1提交任务6任务2开始。总计:2任务3已完成。任务6开始。总计:4任务5已启动。总计:3任务4已启动。总计:4提交任务7任务4已完成。提交任务8任务7开始。总计:4任务5已完成。提交任务9任务7完成。开始了。总计:4任务9已启动。总计:4提交任务10任务2已完成。等待完成...任务10已开始。总计:4任务10已完成。任务6完成。任务8完成。任务9完成。完工!本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处: