我有一个for循环运行500.000ish列表。对于其中的每一个,它都在排队SmartThreadPool作业。
下面的 lines.Length
包含500.000件物品。
我的问题是,我一次排队时会出现内存问题。所以我虽然写了一个逻辑来阻止这个:
int activeThreads = _smartThreadPool2.ActiveThreads;
if (activeThreads < maxThreads)
{
int iia = 0;
for (int i = 0; i < lines.Length; i++)
{
if (doNotUseAdditive.Checked == true)
{
foreach (string engine in _checkedEngines) // Grab selected engines
{
query = lines[i];
_smartThreadPool2.QueueWorkItem(
new Amib.Threading.Func<string, string, int, int, int>(scrape),
query, engine, iia, useProxies);
iia++;
}
}
}
}
else
{
// Wait
wait.WaitOne();
}
问题是我无法在for循环中运行if语句,因为当我回到它时,它将不记得它在循环中的位置。
我正在使用:
ManualResetEvent wait = new ManualResetEvent(false); //global variable
“暂停/恢复”
我需要以某种方式在使用X线程后暂停循环,然后当线程可用时返回并继续循环。
有什么想法吗?
答案 0 :(得分:3)
我不认为处理列表中的每个项目都是一个好主意。即使使用自定义线程池也可能非常容易出错(并且您的示例证明了我的观点)。
首先,您应该正确确定工作线程的数量。您似乎正在处理计算密集型操作(所谓的CPU绑定操作),您应该使用的工作线程数等于逻辑处理器的数量。
您可以使用Parallel LINQ将所有工作集拆分为适当数量的块并并行处理这些块。
Joe Albahari有很多关于这个主题的帖子:Threading in C#. Part 5. Parallel Programming.
这是使用PLINQ的伪代码:
lines
.AsParallel()
.WithDegreeOfParallelism(YourNumberOfProcessors)
.Select(e => ProcessYourData(e));