我是一个班级,说" MyComputation"它在一个长构造函数中进行了大量的计算。它自己执行时通常需要大约20ms才能运行(没有磁盘i / o或网络操作)。这个类的100个左右的实例是由父类创建的,例如" ComputeParent",它将它们作为工作项在ThreadPool中排队:
ThreadPool.QueueUserWorkItem(myComputationCall, my_computation_data);
" myComputationCall"看起来像这样:
public static void myComputationCall(Object my_computation_data)
{
try
{
MyDataObject data = (MyDataObject)my_computation_data;
var computation_run = new MyComputation(data.parameter1, data.parameter2);
data.result = computation_run.result;
}
finally
{
if (Interlocked.Decrement(ref num_work_items_remaining) == 0)
done_event.Set();
}
}
done_event是一个静态的ManualResetEvent:
private static ManualResetEvent done_event;
...
done_event = new ManualResetEvent(false);
对于各种输入参数,我运行ComputeParent约500次左右。所以我有很多嵌套类。问题是执行ComputeParent所需的时间逐渐增加。在运行每个特定的ComputeParent所需的时间之间会有一定的变化,但是时间量会相当稳定地增加(几何上,每次连续迭代需要更长的时间)。
程序的内存消耗虽然很高(~300MB)但并不会随着时间的推移而显着增加。它运行在具有8个逻辑核心的计算机上,处理器的使用似乎非常突发。我不确定还有什么可能与问题有关。
我不希望不必通过批处理文件运行ComputeParent,但完成此操作后似乎不会出现此问题。
答案 0 :(得分:3)
如果ThreadPool中的可用线程数变为0,并且您继续添加新工作项,则新添加的工作项将“等待”。这意味着您的ComputeParent将等待其“myComputationCall”的实例。越来越多的ComputeParent会导致它们的平均执行时间会增加。
答案 1 :(得分:0)
这个问题已得到解答。感谢所有的海报。
对于有类似问题的其他人,我建议按照Henk的建议使用任务并行库。