Запустите пакет процессов и сообщите о прогрессе каждого из них. - PullRequest
1 голос
/ 02 ноября 2011

У меня есть список файлов для шифрования.
Шифрование выполняется внешним приложением консоли, сообщающим о ходе выполнения, которое необходимо проанализировать.Этот прогресс должен быть запущен как асинхронный (Process.BeginOutputReadLine, обрабатывающий событие OutputDataReceived, является единственным способом, которым я могу получить прогресс в реальном времени от этого процесса).

Сценарий:
Для каждого файла, который пользователь выбирает для шифрования,ViewModel экземпляр, содержащий эту информацию о файле, добавляется в ListBox.Пользователь добавил 100 файлов для шифрования.Каждый из ViewModel s имеет команду Encrypt (я использую Prism DelegateCommand), которая должна запускаться, когда пользователь нажимает кнопку Зашифровать в элементе списка.

Кроме тогопользователь может выбрать «Зашифровать все», то есть CompositeCommand в родительском контейнере, который вызывает команду «Шифровать» для каждого отдельного элемента.
Каждый из элементов в списке имеетИндикатор выполнения, указывающий процесс шифрования для этого отдельного файла, и в родительском контейнере также есть индикатор выполнения, который должен отображать общий прогресс.

Я создал оболочку, которая асинхронно вызывает этот процесс и вызывает событие .NET напри каждом изменении прогресса виртуальная машина обрабатывает это событие и обновляет свое свойство прогресса, с которым связана индикатор выполнения, и это событие также обрабатывается родительским контейнером, который сбрасывает итоговый общий индикатор выполнения при каждом изменении прогресса.
Эта оболочка предоставляетФункция «EncryptAsync», которая запускает базовый процесс.
Каждый из элементов (виртуальных машин)имеет оболочку, и когда вызывается команда Encrypt, он вызывает этот метод для оболочки, которая затем создает процесс и т. д.
Таким образом, в основном, когда пользователь нажимает кнопку Encrypt All, запускается 100 процессов.

Просто чтобы убедиться, что шифрование каждого файла может занять до 10 минут и даже больше.Среднее значение - минута или меньше.

Сейчас Моя проблема :

  1. Как ограничить количество одновременных процессов (нужно ли?возможно я должен зашифровать их 1 на 1)?
  2. Это эффективный способ сделать это?Может быть, существует совершенно другой и лучший подход?
  3. Как мне убедиться, что все эти процессы (которые находятся в оболочках, которые находятся в виртуальных машинах) открыты, когда ViewModel закрывается (я сделал все, что могвнутренне распределяя ресурсы (т.е. сам процесс шифрования) после шифрования, но я заставил оболочку реализовать IDisposable, я не уверен, что реализация IDisposable на виртуальной машине будет правильным способом, я ошибаюсь.

Любой дизайн или практическое руководство / ссылки на образцы по этой истории будут очень благодарны!

* Утилизация

Ответы [ 2 ]

1 голос
/ 02 ноября 2011

1. и 2.
Я настоятельно рекомендую вам взглянуть на Как: использовать пул потоков (C # и Visual Basic) в MSDN.
Особенно класс ThreadPoolExample - у него есть решение вашей проблемы

3.
Если вы имеете в виду «продолжить шифрование после закрытия View / VM»: создайте обработку TreadPool в статическом классе.

1 голос
/ 02 ноября 2011

У нас похожая проблема с генерацией отчетов в сервисе, где одновременно могут запрашиваться десятки долгосрочных отчетов. Способ, которым мы обрабатываем потребление ресурсов, заключается в том, что мы раскручиваем каждый отчет в отдельный поток, но ограничиваем максимальное количество исполняемых потоков до определенного числа.

Каждый созданный поток записывается в словарную переменную с использованием ключа, назначенного потоку в момент его создания. Основной процесс управления выполняет непрерывные циклы (спит около 100 мс на цикл) и проверяет завершение каждого из запущенных потоков на каждом проходе.

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

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

Для справки: порождаемые потоки отчетов на самом деле являются классами, содержащими объект Thread, в котором они выполняются. Это позволяет нам контролировать поток или обеспечивать обратную связь с родительским процессом, не пропуская много циклов (просто убедитесь, что вы синхронизируете любые ресурсы, к которым осуществляется доступ как снаружи, так и внутри потока).

...