Я создаю консольное приложение, которое должно обрабатывать кучу данных.
По сути, приложение получает ссылки из БД. Для каждой ссылки проанализируйте содержимое файла и внесите некоторые изменения. Файлы представляют собой файлы HTML, и в процессе выполняется тяжелая работа с заменами RegEx (поиск ссылок и преобразование их в ссылки). Затем результаты сохраняются в файловой системе и отправляются во внешнюю систему.
Если я возобновлю процесс, последовательно:
var refs = GetReferencesFromDB(); // ~5000 Datarow returned
foreach(var ref in refs)
{
var filePath = GetFilePath(ref); // This method looks up in a previously loaded file list
var html = File.ReadAllText(filePath); // Read html locally, or from a network drive
var convertedHtml = ParseHtml(html);
File.WriteAllText(destinationFilePath); // Copy the result locally, or a network drive
SendToWs(ref, convertedHtml);
}
Моя программа работает правильно, но довольно медленно. Вот почему я хочу распараллелить процесс.
К настоящему времени я сделал простую параллелизацию, добавив AsParallel:
var refs = GetReferencesFromDB().AsParallel();
refs.ForAll(ref=>
{
var filePath = GetFilePath(ref);
var html = File.ReadAllText(filePath);
var convertedHtml = ParseHtml(html);
File.WriteAllText(destinationFilePath);
SendToWs(ref, convertedHtml);
});
Это простое изменение уменьшило продолжительность процесса (на 25% меньше времени). Однако я понимаю, что с распараллеливанием не будет больших преимуществ (или, что еще хуже, меньше преимуществ), если распараллеливать ресурсы, полагающиеся на ввод-вывод, потому что ввод-вывод волшебным образом не удваивается.
Вот почему я думаю, что мне следует изменить свой подход, чтобы не распараллеливать весь процесс, а создать зависимые задачи с цепочкой в очереди.
То есть, мне нужно создать поток вроде:
Очередь чтения файла. Когда закончите, Queue ParseHtml. По завершении Queue отправляет на WS и записывает локально. Когда закончите, запишите результат.
Однако я не знаю, как реализовать такую мысль.
Я думаю, что он закончится набором очередей потребителей / производителей, но я не нашел правильного образца.
И более того, я не уверен, будет ли польза.
спасибо за советы
[Edit] На самом деле, я идеальный кандидат для использования C # 4.5 ... если бы это был rtm :)
[Edit 2] Еще одна вещь, заставляющая меня думать, что она неправильно распараллеливается, заключается в том, что в мониторе ресурсов я вижу нестабильные графики ЦП, сетевого ввода-вывода и дискового ввода-вывода. когда один высокий, другие от низкого до среднего