2016-06-13 4 views
0

SendKeys.Send을 사용하는 메서드가 있고, System.Threading.Thread.Sleep을 사용하여 몇 초 기다린 다음 다른 메서드를 실행하여 픽셀의 색을 확인하여 변경되었는지 확인합니다. 그런 다음이 메서드는 재귀 적으로 다시 호출되어 실행됩니다.재귀 메서드가 UI에 변형을 넣습니다.

이 방법은 중지하기 전에 수천 번 실행해야합니다. Winform의 UI가 실행 중일 때 응답을 멈춘 것으로 보입니다.

나는 백그라운드 작업자를 구현하여 UI의 부담을 덜어려고했다. 나는 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. 

UI를 멀리 코드를 이동하는 가장 좋은 방법은 무엇입니까? 나는 배경 작업자들에게 익숙하지 않아서 잘못하고있을 수 있습니다.

+0

배경 작업자를 사용할 수 있습니다. 'Invoke (새 작업 (SendKeys.Send), keys)'를 사용하여 UI 스레드에서 호출을 전달하십시오. – Lou

+1

BGW가 여기에서 도움이되지 않습니다. BGW는 장시간 실행, ** CPU 바인딩 **, * 비 UI * 작업을 다른 스레드로 이동시키기 위해 존재합니다. 당신은 장시간 * IO 바인딩 *, * 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)); 
    } 
} 

이 방법을 사용하면 추가 스레드를 생성하지 않고 지연 기간 동안 UI 스레드가 메시지를 계속 펌핑 할 수 있습니다.

+0

이 메소드를 재귀 적으로 만들 이유는 없습니다. 당신은 자원 소비를 현저하게 증가시키고 실제 이유없이 비 관용적 패턴을 사용합니다. – Servy

+1

@Servy OP 클레임 메서드는이 방식으로 재귀 적으로 호출합니다. 방법은 그것에 충실합니다. 좋은 생각이라고 말하는 것은 아닙니다. –

+0

비동기가 필요한 것입니다. 그 @piedar 주셔서 감사합니다 UI의 부담을 벗어났습니다. 왜 재귀가 이것에 대한 나쁜 생각이 될지 모르지만 그것은 나를 위해 일을하고있다. – Chrayfish

1

동기식 재귀 적 메서드가 아닌 비동기 반복적 메서드를 작성해야합니다.

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

메소드를 재귀 적으로 만드는 것은 아무 것도 추가하지 않습니다. 스택 압력을 반복적으로 제거합니다. 동기식이 아닌 비동기식으로 만들면 UI 스레드를 차단하지 않습니다.