SetWindowPos даже когда основной поток заблокирован? - PullRequest
1 голос
/ 24 марта 2019

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

Я поместил вызов SetWindowPos во вторичный System.Thread, но он все еще заблокирован. Похоже, что SetWindowPos всегда обрабатывается потоком, которому принадлежит окно. Поэтому, если мой основной поток занят, окно не может быть перемещено, даже если запрос отправляется из другого потока.

Есть ли альтернативный способ перемещения окна, даже если поток, которому принадлежит окно, занят? Спасибо!

1 Ответ

2 голосов
/ 24 марта 2019

Я не верю в это. Все операции пользовательского интерфейса должны выполняться в основном потоке приложения, который известен как поток пользовательского интерфейса в приложении с графическим интерфейсом. Будь то событие нажатия кнопки; движение мыши; прокрутки; рисовать и т. д., включая окно перемещения, эти операции ставятся в очередь в приложениях очередь сообщений (что-то вроде буфера FIFO, который Windows поддерживает для всех приложений), которые должны обрабатываться потоком пользовательского интерфейса.

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

Аналогичным образом, если где-то в вашем потоке-коде у вас есть Thread.Sleep(), то пользовательский интерфейс также будет зависать в течение того же периода.

Альтернативы

Возможно, вы захотите перенести длительные операции в другой поток или . Пройдите простой и рекомендуемый путь и используйте async/await. Это позволяет вам выполнять длительную операцию без блокировки пользовательского интерфейса.

Таймеры

Также рассмотрите возможность использования Timer вместо Thread.Sleep() или его эквивалента в качестве альтернативы перемещению окна 100 раз в секунду. Обязательно используйте правильный таймер для приложений с графическим интерфейсом, так как .NET определяет, по крайней мере, четыре (4) я считаю, и не все подходят по умолчанию (если при все) для приложений с графическим интерфейсом .

...