2016-06-13 5 views
0

У меня есть метод, который использует SendKeys.Send, ждет несколько секунд, используя System.Threading.Thread.Sleep, а затем запускает другой метод, чтобы проверить цвет пикселя, чтобы увидеть, изменилось ли оно. Затем метод запускается снова, так как он называется рекурсивно.Рекурсивный метод накладывает деформацию на UI

Этот метод должен иметь возможность запускать тысячи раз перед остановкой. Пользовательский интерфейс Winform, похоже, перестает отвечать на запросы при его запуске.

Я попытался реализовать фона рабочего, чтобы снять напряжение с пользовательского интерфейса. Я переехал код Рекурсивный метод над к Do_Work событию и назвал его RunWorkerAsync, но он разбился, сообщив следующее:

An exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll but was not handled in user code 

Additional information: SendKeys cannot run inside this application because the application is not handling Windows messages. 

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

+0

Вы можете использовать фонового работника, просто используйте 'Invoke (новое действие (SendKeys.Send), ключи)' для отправки вызова в потоке пользовательского интерфейса. – Lou

+1

BGW не поможет вам здесь. BGW существует для продолжения работы **, связанных с процессором **, * не-UI * задач в другой поток. У вас есть длинная работа * IO bound *, * UI * на ваших руках. – Servy

ответ

0

Звучит как случай для async. Попробуйте заменить Thread.Sleep() на Task.Delay().

async void Button_Click(object sender, RoutedEventArgs e) 
{ 
    await SendMyKeysAsync(); 
} 

async Task SendMyKeysAsync() 
{ 
    while (thePixelIsStillRed) 
    { 
     SendKeys.Send("whatever"); 
     await Task.Delay(TimeSpan.FromSeconds(1)); 
    } 
} 

Этот подход выходит из потока пользовательского интерфейса свободно продолжать накачки сообщений в течение периода задержки, без каких-либо дополнительных порождая нитей.

+0

На самом деле нет никакой причины сделать этот метод рекурсивным. Вы просто значительно увеличиваете потребление ресурсов и используете неидиоматический шаблон без какой-либо реальной причины. – Servy

+1

Метод @Servy OP утверждает себя рекурсивно таким образом; метод просто остается верным этому. Не сказать, что это хорошая идея, хотя –

+0

Оказывается, асинк был именно тем, что мне нужно. Спасибо за это @piedar, он снял напряжение с пользовательского интерфейса. Не уверен, почему рекурсивность была бы плохой идеей для этого, но это делает работу для меня. – Chrayfish

1

Вместо синхронного рекурсивного метода вы должны написать асинхронный итерационный метод.

private async void Foo() 
{ 
    while(ShouldKeepLooping()) 
    { 
     SendKeys.Send(keyToSend); 
     await Task.Delay(timespan.FromSeconds(2)); 
    } 
} 

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

 Смежные вопросы

  • Нет связанных вопросов^_^