Как лучше обновлять информацию в контроле из процесса, запущенного в отдельном потоке? Через события, BeginInvoke или через async? Или еще как-то?

Программа запускает длительный процесс в отдельном потоке. Как сейчас, на Шарпе 8-9 технологичнее всего обновлять из потока ListBox на форме информацией о стадиях и успехе выполняемого процесса? Как лучше перезапустить процесс-поток в случае неудачного выполнения? Через исключения в потоке, отлавливая из в главном потоке? Или еще как-то?


Ответы (1 шт):

Автор решения: VladD

Как вам верно сказали в комментариях, у вас три вопроса.

  1. Как обновлять UI?

    Долгоиграющий фоновый процесс относится к модели, и он сообщает о результатах как ему удобно. Если результат один, скорее всего он возвращается в виде промиса Task<T>. Если результатов много, скорее всего вам нужно IAsyncEnumerable<T> или IObservable<T>. Если у вас числомолотилка, может быть, возвращать стоит синхронно материальный результат.

    Часть кода, которая маршаллирует результаты в UI-поток и запускает процесс обновления UI, принадлежит к бизнес-логике. Для Task<T>, например, вообще никаких дополнительных действий не нужно, для IObservable<T> вам нужно ObserveOn и т. д.

  2. Как лучше перезапустить фоновое задание?

    В 2020 году вовсе не нужно использовать сырые потоки. Используйте промисы (Task или Task<T>). Для сообщения об ошибке вам нужны исключения, Task займётся маршаллированием исключений в нужный поток за вас.

  3. Использовать ли исключения для управления фоновыми заданиями?

    Конечно, исключения и try/catch.

→ Ссылка