递归方法对 UI 施加压力

Recursive Method Puts Strain on UI

我有一个使用 SendKeys.Send 的方法,使用 System.Threading.Thread.Sleep 等待几秒钟,然后 运行 使用另一种方法来检查像素的颜色,看它是否有变了。然后该方法再次 运行s,因为它被递归调用。

此方法需要能够 运行 数千次才能停止。 Winform 的 UI 似乎在 运行ning 时停止响应。

我试图实现一个后台工作者来减轻 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 移开的最佳方法是什么?我对后台工作人员不是很熟悉所以我可能做错了。

听起来像是 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 线程可以在延迟期间自由地继续发送消息,而不会产生任何额外的线程。

您应该编写异步迭代方法,而不是同步递归方法。

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

使方法递归不会增加任何内容;使其迭代消除堆栈压力。通过使方法异步而不是同步,您不会阻塞 UI 线程。