Использование BackgroundWorker
- это самый простой способ сделать то, что вы пытаетесь сделать. BackgroundWorker
упрощает логику работы с потоками, оставляя вам очень мало кода, который вам нужно написать. Вам просто нужно обработать три события (DoWork
, ProgressChanged
и RunWorkerCompleted
) и следовать нескольким принципам:
- Никогда не обновляйте интерфейс внутри вашего долгосрочного метода. Вместо этого вызовите
ReportProgress
и обработайте событие ProgressChanged
в логике пользовательского интерфейса.
- Поймите, что, поскольку рабочий не работает в потоке пользовательского интерфейса, исключение, которое выдает ваш метод, автоматически не отображается в пользовательском интерфейсе. Просто молча записывается на консоль. Когда метод завершен, очень важно проверить свойство
Error
RunWorkerCompletedEventArgs
и обработать (или выдать) исключение. Если вы этого не сделаете, вы не узнаете, что ваш метод не удался.
- Если метод можно отменить, убедитесь, что он периодически проверяет свойство
CancellationPending
, чтобы узнать, было ли запрошено аннулирование. Если это так, после завершения отмены установите свойство Cancel
для объекта DoWorkEventArgs
. Помните, что CancellationPending
может быть истинным, а Cancel
ложным; это происходит, например, когда пользователь запрашивает отмену, и метод завершает работу, прежде чем он сможет проверить CancellationPending
.
- Соответственно, отметьте
Cancel
в вашем обработчике RunWorkerCompleted
, чтобы ваш пользовательский интерфейс мог обеспечить правильный ответ на то, что произошло во время работы работника.
Все примеры в документации показывают обработчик события DoWork
, вызывающий метод формы. Это почти наверняка не то, что вы хотите сделать. Отделение бизнес-логики от пользовательского интерфейса является хорошей идеей в целом; в фоновых задачах это важно. Если ваш долгосрочный метод является членом класса, который не знает, что пользовательский интерфейс даже существует, нет никакой опасности, что он случайно вызовет метод, который обновляет строку состояния или что-то в этом роде.