.NET 4.x Прошу консультации экспертов (ООП, многопоточность) - C#
Формулировка задачи:
Здравствуйте! Давеча пытался устроиться на работу и прислали мне тестовое задание, далее привожу его текст:
В общем посидел пару вечеров и наваял прогу на сколько позволяли знания и навыки. Поскольку ранее ничего подобного не делал, поначалу даже показалось, что задание несложное. Однако отправляя проект не оставляло ощущение, что сделал не так как надо.
Так в итоге и оказалось. Мне вежливо отказали дополнив комментариями касательно кода:
Собственно чтобы я хотел попросить: прокомментировать код, указать на проблемные места и предложить пример более удачной реализации. Хочу понять где слабые места и что надо подтянуть в плане знаний и навыков. Заранее всем благодарен!
Требуется написать консольную программу на C# для генерации сигнатуры указанного файла. Сигнатура генерируется следующим образом: исходный файл делится на блоки заданной длины (кроме последнего блока), для каждого блока вычисляется значение hash-функции SHA256, и вместе с его номером выводится в консоль.
Программа должна уметь обрабатывать файлы, размер которых превышает объем оперативной памяти, и при этом максимально эффективно использовать вычислительные мощности многопроцессорной системы. При работе с потоками допускается использовать только стандартные классы и библиотеки из .Net 3.5 (исключая ThreadPool, BackgroundWorker, TPL). Ожидается реализация с использованием Thread-ов. Путь до входного файла и размер блока задаются в командной строке. В случае возникновения ошибки во время выполнения программы ее текст и StackTrace необходимо вывести в консоль.
1. Вся программа в одном файле, двух классах и нескольких статических методах. ООП нет.
Классы не являются лишними, если у них есть понятная область отвественности.
В данном случае, если бы выделили класс для запуска потоков и отслеживания их завершения – то это не было бы лишним.
2.Алгоритм работы не эффективный. Файл сразу бьется на блоки и для каждого блока стартует новый поток. Все сразу. Никого thread pool нет.
Для подсчета хэша каждого блока запускается отдельный поток. Запуск потока трудоемкая операция, которая требует много ресурсов. Вариантов решения этой проблемы возможно несколько. Или реализовывать свою вариацию threadPool или использовать долгоживущие потоки.
Кроме того, сейчас никак не ограничивается число запущенных потоков. При их большом количестве, они будут бороться за процессорное время и значительная часть ресурсов будет тратиться на переключение контекстов между потоками.
3.Ожидание окончания всех потоков на Thread.Sleep
Ожидание завершения на Thread.Sleep является ресурсоемким. Поскольку основной поток, ждущий завершения, постоянно просыпается и занимает процессорное время, которое можно было потратить на обсчет следующего блока. Для решения этих проблем используют примитивы синхронизации.
Проверка окончания всех потоков происходит на статической перемерной threadCount. К ней осуществляется доступ из нескольких потоков, и доступ никак не синхронизирован.
Это стандартная проблема разделения ресурсов между и не исключена ситуация, что threadCount никогда не достигнет 0.
Решение задачи: «.NET 4.x Прошу консультации экспертов (ООП, многопоточность)»
textual
Листинг программы
using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Threading.Tasks; namespace ThreadTests { class Program { private static int count = 0; static void Main(string[] args) { var tasks = new List<Task>(); for (int i = 0; i < 5000; ++i) tasks.Add(Task.Run(() => NoAction())); foreach (var t in tasks) t.Wait(); Console.WriteLine(count); } [MethodImpl(MethodImplOptions.NoInlining)] static void NoAction() { count++; } } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д