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

Aon*_*rtt 9 c# performance multithreading threadpool

我有一个类,说"MyComputation",它在一个长构造函数中进行了大量的计算.它自己执行时通常需要大约20ms才能运行(没有磁盘i/o或网络操作).这个类的100个左右的实例是由父类创建的,比如"ComputeParent",它将它们作为工作项在ThreadPool中排队:

ThreadPool.QueueUserWorkItem(myComputationCall, my_computation_data);
Run Code Online (Sandbox Code Playgroud)

"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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

done_event是一个静态的ManualResetEvent:

    private static ManualResetEvent done_event;

    ...

    done_event = new ManualResetEvent(false);
Run Code Online (Sandbox Code Playgroud)

对于各种输入参数,我运行ComputeParent约500次左右.所以我有很多嵌套类.问题是执行ComputeParent所需的时间逐渐增加.在运行每个特定ComputeParent所需的时间之间会有一定的变化,但是时间量会相当稳定地增加(几何上,每次连续迭代需要更长的时间).

程序的内存消耗虽然很高(~300MB),但并不会随着时间的推移而显着增加.它运行在具有8个逻辑核心的计算机上,处理器的使用似乎非常突发.我不确定还有什么可能与这个问题有关.

我不希望不必通过批处理文件运行ComputeParent,尽管在完成此操作后似乎不会出现问题.

Ale*_*y F 3

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