C#ThreadPool应用程序性能随着时间的推移而降低

时间:2012-05-09 20:02:18

标签: c# multithreading performance threadpool

我是一个班级,说" 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,但完成此操作后似乎不会出现此问题。

2 个答案:

答案 0 :(得分:3)

如果ThreadPool中的可用线程数变为0,并且您继续添加新工作项,则新添加的工作项将“等待”。这意味着您的ComputeParent将等待其“myComputationCall”的实例。越来越多的ComputeParent会导致它们的平均执行时间会增加。

答案 1 :(得分:0)

这个问题已得到解答。感谢所有的海报。

对于有类似问题的其他人,我建议按照Henk的建议使用任务并行库。