Когда поток пользовательского интерфейса находится в спящем режиме, может ли он вызывать методы из фоновых потоков в течение неопределенного времени? - PullRequest
2 голосов
/ 23 сентября 2010

Когда я вызываю Thread.Sleep в потоке пользовательского интерфейса, все ли вызываемые методы из фонового потока автоматически помещаются в очередь в потоке сообщений потока пользовательского интерфейса и обрабатываются, когда он в конце концов просыпается?

У меня проблемы с приложением winform, которое использует много потоков потоков, а иногда приложение зависает после блокировки / разблокировки Windows. Можно предположить, что в потоке пользовательского интерфейса произошла тупиковая ситуация. Другой - некоторые элементы управления пользовательского интерфейса создаются в фоновых потоках. (как это может вызвать проблемы ???)

Ответы [ 2 ]

1 голос
/ 23 сентября 2010

Да, тупиковая ситуация при разблокировке рабочей станции - довольно печально известная проблема с многопоточностью Windows Forms. У меня никогда не было хорошего диагноза, но я уверен, что это вызвано классом SystemEvents. Это проблема инициализации программы, класс инициализируется по требованию, когда элементы управления начинают подписываться на его события.

Я думаю, что в режиме сбоя создается первая форма в потоке, отличном от основного потока программы. Вы получите это, скажем, когда создадите свой собственный экран-заставку вместо использования .NET. Или раскручивая поток, который создает собственный экземпляр формы, и запускает его слишком рано. В результате SystemEvents будет запускать свои события из неправильного потока. Событие SystemSwitch как-то смертельно.

Итак, посмотрите на код вашего запуска с помощью зубчатого гребня. Подписка на одно из системных событий в вашем методе Main () перед выполнением чего-либо важного должна быть исправлением вопросов и ответов.

1 голос
/ 23 сентября 2010

Правило таково, что только поток, который создает элемент управления UI, должен связываться с ним.Это одна из причин, по которой вообще существует «поток пользовательского интерфейса», и он не дает вам угадывать, нужно ли вам Invoke что-то делать или просто делать это.(Если событие происходит из элемента управления пользовательского интерфейса, оно находится в потоке пользовательского интерфейса, так что вы можете просто сделать это. В противном случае Invoke.) Итак, вы хотите создать свои элементы управления в этом потоке, и пусть это будет тот, который обрабатывает всепользовательский интерфейс в том виде, в котором он был предназначен.

Ваш поток пользовательского интерфейса имеет одну цель: обрабатывать все события из пользовательского интерфейса, чтобы приложение реагировало и не выглядело "замороженным".Иногда он будет занят (от обработки других событий), но всегда должен либо обрабатывать событие, либо ждать другого. Никогда не звоните Thread.Sleep в потоке пользовательского интерфейса , если у вас нет чертовски веских причин и вы не можете конкретно сказать, почему это не ужасная идея.Почти все, что вы хотели бы сделать с Thread.Sleep, можно вместо этого обрабатывать с помощью таймеров и быть гораздо менее шатким.

Короткая версия: да, если поток пользовательского интерфейса что-то делает (даже спит), вызываетControl.Invoke почти наверняка подождет, пока это не так.Если нить спит, это может занять очень много времени.

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