BackgroundWorker может вызывать зависание моего приложения - PullRequest
0 голосов
/ 16 июня 2010

У меня есть форма, которая использует BackgroundWorker для выполнения серии тестов. Я использую событие ProgressChanged для отправки сообщений в основной поток, который затем выполняет все обновления в пользовательском интерфейсе. Я прочесал свой код, чтобы убедиться, что я ничего не делаю с пользовательским интерфейсом в фоновом режиме. В моем коде нет циклов while, а у BackgroundWorker конечное время выполнения (измеряется в секундах или минутах). Однако по какой-то причине, когда я блокирую свой компьютер, часто приложение зависает при повторном входе в систему. Дело в том, что BackgroundWorker даже не запускается, когда это происходит. Причина, по которой я считаю, что это связано с BackgroundWorker, заключается в том, что форма зависает только тогда, когда BackgroundWorker был выполнен с момента загрузки приложения (он запускается только при наличии определенного пользовательского ввода).

Я передаю этому потоку список TreeNodes из TreeView в моем пользовательском интерфейсе с помощью метода RunWorkerAsync, но я читаю только эти узлы в рабочем потоке. Любые изменения, которые я в них выполняю, выполняются в потоке пользовательского интерфейса через событие progressChanged. .

Я использую Thread.Sleep в моем рабочем потоке для выполнения тестов через определенные промежутки времени (что включает в себя отправку сообщений через сокет TCP, который не был создан в рабочем потоке).

Я полностью озадачен тем, почему мое приложение может зависать. Я уверен, что я делаю что-то «незаконное» где-то, я просто не знаю, что.

Ответы [ 3 ]

1 голос
/ 16 июня 2010

Я передаю этому потоку список TreeNodes из TreeView в моем пользовательском интерфейсе через метод RunWorkerAsync, но я читаю только эти узлы в рабочем потоке.

Под словом "только чтение" я предполагаю, что вы имеете в виду "только получатели доступа к свойствам". Но методы получения свойств могут выполнять код, который вы не контролируете - например, TreeNode.IsSelected будет вызывать собственный метод и отправлять сообщение Windows (взгляните на Reflector).

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

0 голосов
/ 27 мая 2011

Ну, этот старый, но оказалось, что проблема была совершенно не связана с моим кодом.Из-за недавних изменений в нашем программном обеспечении объем журналирования увеличился в геометрической прогрессии, и наш буфер журналов переполнился, что привело к сбою приложения.Это было просто совпадение, что это происходило в то же время, когда я работал над этим конкретным фрагментом кода.В любом случае я по-прежнему следил за тем, чтобы не выполнять никаких операций над элементами пользовательского интерфейса из BackgroundWorker, даже если это было так же тривиально, как проверка / снятие флажка TreeNode.

0 голосов
/ 31 декабря 2010

Похоже на страшную проблему UserPreferenceChanged, когда компонент пользовательского интерфейса был создан в фоновом потоке без прокачки сообщений.Основной поток пользовательского интерфейса синхронно отправляет событие всем зарегистрированным окнам пользовательского интерфейса и зависает, поскольку компонент пользовательского интерфейса в фоновом рабочем потоке не может обработать событие UserPreferenceChanged.

...