1

Пока реализовываю задачу с помощью System.Thread,нужно сделать эту же задачу с помощью System.Task

Предполагая, что в некотором каталоге на диске сохранено большое количество файлов с логами (журналами работы) прокси-сервера, написать программу вычисляющую статистику потребления трафика сети Интернет. На выходе программа должна создавать три текстовых документа: статистика по пользователям, статистика по доменам, статистика по датам. В качестве статистики использовать общий объем потребленного трафика, соответственно пользователем за все дни, при обращении к домену, в указанный день. При разработке программы считать, что каждый файл должен обрабатываться отдельно параллельно выполняющимся участком кода. После обработки всех файлов, полученные результаты для каждого из них должны суммироваться в общую сводку.

Нужна помощь в составлении алгоритма,код я не прошу. Просто словесное описание как можно это сделать с помощью System.Task

А код я потом напишу и если будут вопросы то скину сюда.

andreycha
  • 25,167
  • 4
  • 46
  • 82
beginner
  • 380
  • пример работы с Task - тут после update. – Stack Jan 09 '16 at 13:27
  • Опишите, что вы уже знаете про Task и async/await. Рассказать вам про то, что это такое и как с ним работать с нуля — это тянет на хорошую, длинную статью, двумя словами тут не обойтись. – VladD Jan 09 '16 at 14:36
  • содержимое текстовых файлов такое же как тут? сколько таких файлов примерно. и сколько строк бывает в файле? если объемы небольшие. то решение - одно, а если логи гигабайтные и user'ов миллионы, то решение должно быть другое. – Stack Jan 09 '16 at 16:16
  • Да да такое же. у меня 10 текстовых в каждом максимум 10 строк.

    Мне тоже их надо парсить как с потоками или нет?

    – beginner Jan 09 '16 at 16:34

1 Answers1

2

в некотором каталоге на диске сохранено большое количество файлов с логами

Для чтение каталога: Directory.EnumerateFiles -- по мере чтения файлов возвращает их названия и путь.

файл должен обрабатываться отдельно параллельно выполняющимся участком кода.

Все что связано с обработкой файла надо вынести в отдельный метод, который будет получать путь к файлу, и возвращать результат обработки.

TrafficStat Process(string filePath) {
   var stat = new TrafficStat();
   // загрузка и обработка файла
   return stat;
}

Этот метод можно вызывать из разных потоков, например, так

using System.Threading.Tasks;

foreach(var file in Directory.EnumerateFiles(@"c:\temp\", "log*.txt")) {
   Task.Run(() => {
      var stat = Process(file);
      // сохраняем stat в файл
   });
}

результаты для каждого из них должны суммироваться в общую сводку.

Т.к. обработка файлов происходит в разных потоках, то надо дождаться завершение потоков, и только после этого можно собрать сводку.

using System.Threading.Tasks;

TrafficStat Process(string path) { 
   // обрабатываем файл, собираем статистику 
}

// запускаем обработку файлов в разных потоках
var ts = Directory.EnumerateFiles(@"C:\Temp\", "log*.txt")
                  .Select(file => Task.Run(() => Process(file)));

// ждем завершение
Task.WaitAll(ts.ToArray());

// собираем сводку
var result = new int[3];
foreach (var t in ts) {
    if (t.Exception != null) Console.WriteLine(t.Exception);
    else {
        var stat = t.Result;        // TrafficStat
        res[0] += stat.Items.Where(i => i.Key == "User").Sum(i => i.Traffic);
        res[1] += stat.Items.Where(i => i.Key == ...
    }
}

Для работы Task используются потоки из пула потоков. Подробнее тут.
Вместо Task.WaitAll можно использовать AttachedToParent, см. тут.
Пример парсера лог файла тут.

Stack
  • 9,452