問題のパフォーマンス特性を理解できるような単純なものから始めるのが最善の策だと思います。
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
それらのパラメーターを 1 つのオブジェクトにラップして、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;
}
また、処理する必要があるファイルの数を確認することをお勧めします。何もない場合は、タイマーを再度有効にして戻ります。これにより、実際には何もしない一連の操作がキューに入るのを回避できます。