AsyncItemsTask – обработчик заданий в отдельном потоке (C#)

Небольшая шаблонная конструкция для обработки “тяжелого” кода в отдельном потоке и уведомления о прогрессе выполнения основного потока программы.

Да, я отдаю себе отчет в том, что такое может и/или должно решаться иначе в мире .Net, но.. фиг с ним.

В WPF-программах можно взаимодействовать с пользовательским интерфейсом только из основного потока, поэтому методы с обработкой результата нужно вызывать именно “оттуда”, например, путем использования Dispatcher.Invoke(). Для этого в конструкцию необходимо передать параметр типа DispatcherObject, дальний потомок которого является класс Window.

TParamCollection, TParamItem и TResult – это типы коллекции, элементов коллекции и результата обработки этой коллекции соответственно. 

Последовательность вызова методов шаблона такова:
1) PreUI() – перед началом обработки коллекции. Тут можно включить какой-нибудь ProgressBar или анимашку.
2) Run() – для непосредственной обработки элементов.
2.1) PreItemUI() – перед обработкой элемента.
2.2) PostItemUI() – после обработки элемента (с результатом типа bool). Увеличиваем % в ProgressBar.
3) PostUI() – после обработки всей коллекции (с результатом типа TResult). Выключаем ProgressBar.
4) StopUI() – при вызове метода Stop() вызовется этот. Также выключаем ProgressBar.

Методы с суффиксом UI будут запускать в основном потоке.

Для запуска всей этой херни:
1) создать наследника AsyncItemsTask и переопределить UI-методы.
2) создать экземпляр класса AsyncItemsTask, с передачей параметра с формой.
3) запустить метод Start(), с передачей самой коллекции.

 

Может использоваться, например, так (где MainWindow – объект типа Window):

Вспомогательный класс GroupOperationResult для возврата детального результата:

Кстати, есть класс таймера System.Windows.Threading.DispatcherTimer, callback-код которого выполняется в рамках потока пользовательского интерфейса и без всяких Dispatcher.Invoke(), тут си-шарперы подумали за нас.

 

Добавить комментарий

Ваш адрес email не будет опубликован.