что я должен избегать делать в фоновом потоке в winforms - PullRequest
1 голос
/ 22 марта 2009

Помимо обновления элементов управления графическим интерфейсом из фоновых потоков, есть ли другие операции, которые следует избегать в фоновых потоках в winforms?

Ответы [ 4 ]

3 голосов
/ 22 марта 2009

О, здесь много ловушек. BGW мало что делает, чтобы защитить вас от обычных опасностей многопоточного программирования. И добавляет некоторые свои:

  • Переменные, к которым осуществляется доступ как из BGW, так и из потока пользовательского интерфейса, должны быть защищены блокировкой.
  • Не обновлять связанный источник данных в BGW. Обновления элемента управления будут выполняться в потоке BGW, но не будут генерировать исключение.
  • Не вызывайте ReportProgress () слишком часто. Выполнение этого более 1000 раз в секунду приведет к зависанию потока пользовательского интерфейса. Достаточно примерно 25 раз / сек.
  • Осторожнее с аргументом usertate, который вы можете передать ReportProgress (). Он не должен быть изменен BGW после вызова.
  • Не зацикливайте свойство IsBusy в потоке пользовательского интерфейса, оно заблокируется.
  • Поток BGW будет прерван при закрытии основной формы. Остерегайтесь необходимой очистки.
  • Обязательно проверьте свойство Error в событии RunWorkerCompleted, оно сообщает, когда что-то пошло не так.
2 голосов
/ 22 марта 2009

Это довольно широкий. Не делайте ничего в фоновом потоке, если вам это не нужно; то есть не используйте какой-то код только потому, что вам это нравится. Используйте потоки там, где это уместно, например, для длительных задач, которые вы не хотите прерывать GUI и так далее. Кроме того, если вы в конечном итоге просто вызываете Application.DoEvents () из основного потока пользовательского интерфейса, ожидающего выполнение задачи из другого потока, вы можете подумать о том, чтобы сохранить один поток и выполнять работу небольшими частями в цикле, где вы будете перерисовывать графический интерфейс с вызовами DoEvents (). Это просто предложение; однако, конечно, много раз вам нужно создавать несколько потоков.

Возможно, вы можете спросить о конкретных ситуациях?

1 голос
/ 22 марта 2009

Ну, причина, по которой вы не должны обновлять элементы управления GUI в фоновом потоке, заключается в том, что классы элементов управления GUI не являются потокобезопасными. Таким образом, вы можете обобщить это: не связывайтесь с экземплярами не поточно-безопасных классов из фонового потока, если есть какой-то другой поток, который также может их использовать. (Я знаю, это широко, но все, что нарушает это правило, может привести к неприятностям).

Но я думаю, что суть вашего вопроса заключается в том, охватили ли вы все основы, которые Control.Invoke() был создан, чтобы покрыть. Если да, то у вас есть ... Control.Invoke был специально разработан для того факта, что элементы управления не являются потокобезопасными, и поэтому другие потоки должны изменять элементы управления только через Control.Invoke().

0 голосов
/ 22 марта 2009

Я согласен с Бобби, что ваш вопрос слишком широк. Вместо этого начните с предположения, что если вам нужно создать рабочий поток, вы не собираетесь помещать в него ничего, кроме того, что обязательно должно быть там , чтобы выполнить требуемую задачу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...