2017-01-20 3 views
-3

У меня есть приложение C#, в котором я взаимодействую с другим окном через API Windows: (например, FindWindow(), FindWindowEx()).Thread.Sleep() или while()?

В одной конкретной части приложения я должен дождаться загрузки окна другого приложения, прежде чем нажимать кнопку, которая появляется (иногда для ее отображения требуется до трех секунд).

В настоящее время я делаю это:

IntPtr foohWnd = IntPtr.Zero; 
while(foohWnd == IntPtr.Zero) 
    foohWnd = FindWindow(null, "Foo"); 

Как вы можете видеть, это просто продолжает проверки окна снова и снова и снова, не заботясь о ресурсах или что-нибудь подобное. (Не волнуйтесь, в моем фактическом коде это «тайм-аут» после бит, чтобы предотвратить бесконечный цикл).

Однако, другой способ я нашел, чтобы сделать это с помощью Thread.Sleep():

Thread.Sleep(3000); 
foohWnd = FindWindow(null, "Foo"); 

Какой из этих двух является лучшей практикой? Есть ли еще лучший способ, чтобы я проигнорировал здесь?

+2

Почему бы не объединить их с вами, чтобы спать в вашей петле, чтобы вы не привязывали процессор? – juharr

+3

Ни один из них не является особенно удовлетворительным. В идеальном мире вы получите другой процесс, чтобы перезвонить вам, когда он будет готов. Если этот процесс выходит из-под контроля, используйте цикл while, но вставляйте короткий сон в него, чтобы избежать горячего процессора. –

+2

«Есть ли еще лучший способ ...» - возможно, зависит от того, почему вы решили перейти на уровень API Windows в первую очередь. Например. использование UI Automation, чтобы вы могли взаимодействовать на более семантическом уровне, может быть уместным. Мы не знаем, что вы делаете, когда найдете * это окно. –

ответ

0

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

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

0

Вы можете смешать оба aproches:

IntPtr foohWnd = IntPtr.Zero; 
while(foohWnd == IntPtr.Zero) 
{ 
    Thread.Sleep(1000); 
    foohWnd = FindWindow(null, "Foo"); 
} 

Хотя consmes CPU, но только сон не работает, когда окно apears после более чем на 3 сек.

5

Try:

await Task.Delay(TimeSpan.FromSeconds(30)); 

Это асинхронный способ и поток не будет заблокирован.

+0

Я решил пойти по этому маршруту, спасибо @ Тито. – Ellis

+5

Правильный ответ на неправильное решение. OP действительно необходимо использовать [WinEvents] (https://msdn.microsoft.com/en-us/library/windows/desktop/dd373889.aspx), потому что так вы ожидаете создания окна. Приостановка потоков работает над проблемой, вызванной выбором неправильного решения. – IInspectable

+0

Повторяя настроение IInspectable, но добавляя: Итак, если поток не будет заблокирован, что произойдет во время ожидания? Модальный цикл сообщений? Потому что что-то еще не имеет особого смысла ... – andlabs