Возможно, петли не нужны, параллель тоже не нужна. Это было бы полезно, если вы хотите обработать пакет новых файлов.
FileSystemWatcher в папке, где появятся новые файлы, даст вам событие для добавления файла в очередь.
Добавить событие для элемента, добавленного в очередь, чтобы запустить поток для обработки отдельного файла.
Если вы выберете простой класс, Файл, состояние, обнаруженное время и т. Д.
У вас есть поток обнаружения, добавляющий в очередь, пул потоков для их обработки и, при успешном удалении, из очереди.
Этот предыдущий вопрос может оказаться полезным для "безопасных" списков в .net 4
Потокобезопасный список свойство
Особенно, если вы хотите обработать все новые файлы начиная с X.
Обратите внимание, что если вы не собираетесь использовать FileSystem watcher и просто получать файлы из папки, то Обработанная папка для их перемещения и, возможно, также и Папка с ошибками, была бы хорошей идеей. Считывание 200,00 имен файлов, чтобы проверить, обработали ли вы их, отчасти исключило бы какую-либо выгоду от их параллельной обработки.
Даже если вы это сделаете, я бы порекомендовал это. Простое перемещение его обратно в To Process (или после редактирования в случае сбоев) приведет к повторной обработке. Еще одно преимущество, скажем, если вы выполняете обработку в базе данных, и все это соскакивает вверх, а ваша последняя резервная копия была в X. Вы восстанавливаете, а затем просто перемещаете все файлы, которые вы обработали, обратно в папку «toprocess».
Вы также можете выполнять тестовые прогоны с известным вводом и проверять состояние БД до и после.
Далее к комментарию.
В ThreadPool, который используется Task, установлен предел ThreadPool, предназначенный для всех или фоновых задач в вашем приложении.
После комментария.
Если вы хотите ограничить количество одновременных задач ...
Стартер на десять, который вы можете легко улучшить для настройки и повышения.
В вашем классе, который управляет выпуском задач из очереди файлов, что-то вроде
private object _canRunLock;
private int _maxTasks;
private int _activeTasks;
public MyTaskManager(int argMaxTasks)
{
_maxTasks = argMaxTasks;
_canRunLock = new object();
_activeTasks = 0;
}
public bool CanRunTask(MyTask argTask)
{
get
{
lock(_canRunLock)
{
if (_activeTasks < _maxTasks)
{
ExecuteTask(argTask);
_activeTasks++;
return true;
}
}
return false;
}
}
public void TaskCompleted()
{
lock(_canRunLock)
{
if (_activeTasks > 0)
{
_activeTasks--;
}
else
{
throw new WTFException("Okay how did this happen?");
}
}
}
Просто и безопасно (я думаю). Вы можете сделать еще одно свойство приостановить или отключить, чтобы проверить. Возможно, вы захотите сделать вышеперечисленное синглтоном (:() или, по крайней мере, иметь в виду, что если вы запустите более одного ...
Лучший совет, который я могу дать, это начать с простого, открытого и отсоединенного, а затем усложнить при необходимости, легко начать преждевременную оптимизацию здесь. Хорошая идея - не загружать все потоки, ожидающие, скажем, FileSystem или бэкэнда, но я сомневаюсь, что количество процессоров когда-нибудь станет узким местом, так что ваши maxTasks немного в воздухе.
Какая-то самостоятельная настройка между нижним и верхним пределами может быть хорошей вещью, а не одним фиксированным числом.