为线程完成一个队列线路的最佳方式是什么,以便我只能拥有最大数量的线程,并且如果我已经有很多代码在等待空闲槽之前继续..在继续执行代码之前等待空闲的线程槽号
我的意思伪codeish例子,我确信这可以以更好的方式来完成...
(请检查下面的附加要求)
private int _MaxThreads = 10;
private int _CurrentThreads = 0;
public void main(string[] args)
{
List<object> listWithLotsOfItems = FillWithManyThings();
while(listWithLotsOfItems.Count> 0)
{
// get next item that needs to be worked on
var item = listWithLotsOfItems[0];
listWithLotsOfItems.RemoveAt(0);
// IMPORTANT!, more items can be added as we go.
listWithLotsOfItems.AddRange(AddMoreItemsToBeProcessed());
// wait for free thread slot
while (_CurrentThreads >= _MaxThreads)
Thread.Sleep(100);
Interlocked.Increment(ref _CurrentThreads); // risk of letting more than one thread through here...
Thread t = new Thread(new ParameterizedThreadStart(WorkerThread(item));
t.Start();
}
}
public void WorkerThread(object bigheavyObject)
{
// do heavy work here
Interlocked.Decrement(ref _CurrentThreads);
}
看着Sempahore
但似乎需要在t内运行他在线程创建之前并不在外线。在这个例子中,Semaphore在线程内部被创建后用于暂停它,在我的情况下,可能有超过10万个线程需要在作业完成之前运行,所以我宁愿在插槽可用之前创建线程。 (link to semaphore example)
在实际应用中,数据可以被添加到项目列表的程序进行所以Parallel.ForEach
将没有真正的工作是(我在SSIS这样的脚本组件包发送数据到一个非常慢的WCF)。
SSIS具有.NET 4.0
您是否尝试过使用Semaphore和SemaphoreSlim? https://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim%28v=vs.110%29.aspx – 2015-02-09 15:40:56
@ Benji_9989是的,请看我添加的评论。 – JensB 2015-02-09 15:42:56
倾向于使用类似['Parallel.ForEach']的构造(https://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach%28v=vs.110%29.aspx )使用MaxDegreeOfParallelism选项,而不是手动创建和管理线程(如果可能的话)。 – 2015-02-09 15:46:07