递归方法在UI

时间:2016-06-13 23:06:37

标签: c# multithreading recursion backgroundworker sendkeys

我有一个利用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移开的最佳方法是什么?我对背景工作者不太熟悉,所以我可能做错了。

2 个答案:

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