我有一个利用SendKeys.Send
的方法,使用System.Threading.Thread.Sleep
等待几秒钟,然后运行另一种方法来检查像素的颜色以查看它是否已更改。然后该方法再次运行,因为它是递归调用的。
此方法需要能够在停止前运行数千次。 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 :(得分:1)
您应该编写异步迭代方法,而不是同步递归方法。
private async void Foo()
{
while(ShouldKeepLooping())
{
SendKeys.Send(keyToSend);
await Task.Delay(timespan.FromSeconds(2));
}
}
使该方法递归不会增加任何内容;使迭代移除堆栈压力。通过使方法异步而不是同步,您不会阻止UI线程。
答案 1 :(得分: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线程可以在延迟期间自由地继续传送消息,而不会产生任何额外的线程。