我认为你最好的选择是从一些简单的事情开始,这样你就可以了解问题的性能特征。
List<string> items = GetListOfPdfFilesToProcess();
int numCores = 4;
int maxListChunkSize = (int)Math.Ceiling(items.Count / (double)numCores);
ManualResetEvent[] events = new ManualResetEvent[numCores];
for (int i = 0; i < numCores; i++)
{
ThreadPool.QueueUserWorkItem(ProcessFiles, new object[]
{
items.Skip(i * maxListChunkSize).Take(maxListChunkSize).ToList(), events[i]
});
}
WaitHandle.WaitAll(events);
....
private static void ProcessFiles(object state)
{
object[] stateArray = (object[])state;
List<string> filePaths = (List<string>)stateArray[0];
ManualResetEvent completeEvent = (ManualResetEvent)stateArray[1];
for (int i = 0; i < filePaths.Count; i++)
{
csCommon.pdfFilesCompressAndMove(your parameters);
}
completeEvent.Set();
}
这里的主要是将工作分成numCores
块。这样,您应该能够充分利用所有 CPU 内核,同时保持一个非常简单的编程模型。
请记住,这不会进行任何错误处理 - 您需要处理它。csCommon.pdfFilesCompressAndMove
如果无法处理文件,也可能需要考虑一下该怎么做。最简单的方法是记录错误并稍后检查,但如果您认为下次会成功,您可以尝试重新处理该文件。
您会注意到该state
对象只是一个数组;如果您需要传递大量参数,ProcessFiles
那么将这些参数包装到单个对象中并将其作为state
.
编辑:
要从您的Tick
活动中使用:
private void TimerTick(object sender, EventArgs e)
{
//Disabling the timer will ensure the `TimerTick` method will not try to run
//while we are processing the files. This covers the case where processing takes
//longer than 2 minutes.
timer.Enabled = false;
//Run the first block of code in my answer.
//Reenabling the timer will start the polling back up.
timer.Enabled = true;
}
我还建议检查您必须处理的文件数量:如果没有,请重新启用计时器并返回。这将避免排队一堆实际上不做任何事情的操作。