Проблема в том, что вам нужен цикл сообщений, чтобы любой элемент интерфейса работал правильно. Поскольку вы создаете форму в рабочем потоке, цикл сообщений не выполняется. Чтобы создать цикл сообщений, вы должны позвонить Application.Run
или Form.ShowDialog
, оба из которых блокируют вызовы. Очевидно, что это решение повредит ваш рабочий поток.
Лучше всего создать отдельный поток, предназначенный для запуска цикла сообщений и который может безопасно обрабатывать формы и элементы управления. Пусть рабочий поток периодически публикует информацию о ходе выполнения в переменную, которая может быть разделена между рабочим потоком и потоком интерфейса пользователя. Затем периодически проводите опрос потока пользовательского интерфейса (используя System.Windows.Form.Timer) с этой общей переменной и соответственно обновляйте пользовательский интерфейс.
В качестве примечания, я бы не стал использовать Control.Invoke
или Control.BeginInvoke
для передачи информации о ходе выполнения в поток пользовательского интерфейса. Ваша ситуация, кажется, оправдывает подход опроса. Причины предпочтения опроса над нажатием:
- Это нарушает тесную связь между пользовательским интерфейсом и рабочими потоками, которые навязывает
Control.Invoke
.
- Он возлагает ответственность за обновление потока пользовательского интерфейса на поток пользовательского интерфейса, к которому он все равно должен принадлежать.
- Поток пользовательского интерфейса определяет, когда и как часто должно происходить обновление.
- Нет риска переполнения насоса сообщений пользовательского интерфейса, как в случае с методами маршалинга, инициированными рабочим потоком.
- Рабочему потоку не нужно ждать подтверждения того, что обновление было выполнено, прежде чем переходить к следующим шагам (т. Е. Вы получаете большую пропускную способность как для пользовательского интерфейса, так и для рабочих потоков).