在异步方法中使用await来防止下一行代码运行

时间:2017-03-01 15:17:14

标签: c# winforms async-await cefsharp

我是使用异步方法的新手,所以我觉得我误解了一些东西。我有一个带按钮的WinForms应用程序,当单击该按钮时,会调用异步方法。这必须是异步的,因为我需要对Chromium Web Browser控件进行javascript调用(使用CefSharp)。我需要确保这个javascript已经完成运行并且浏览器已经更新,然后再继续使用该方法的下一部分。

我基本上试图将整个网页捕获为单个图像。我的方法是使用javascript更新页面上的滚动位置,然后使用Graphics.CopyFromScreen在每个位置截取屏幕截图。这种情况大多有效,但偶尔会产生错误的“大块”图像。网页(例如,第一个位图重复两次)。这是我的代码:

// Calculate screen sizes, screenshot spacing etc.

for (int i = 0; i < screenshotCount; i++)
{
    int scrollSize = i == 0 ? -PageHeight : (int)browserControlHeight;
    string script = "(function() { window.scrollBy(0, " + scrollSize.ToString() + ") })();";

    await browser.EvaluateScriptAsync(script);

    // Take screenshot, add to list of bitmaps
}

// Combine resulting list of bitmaps

如果我添加以下内容

await Task.Delay(1000);

在EvaluateScriptAsync()调用之后,每次最终图像都是正确的。我假设javascript正在被调用,但在屏幕截图开始之前没有完成。如果是这种情况,即使添加延迟也可能无效(如果javascript运行的时间超过一秒,该怎么办?)。

我是否误解了async / await的工作方式?

1 个答案:

答案 0 :(得分:5)

不,问题不在于await,问题是Task返回的EvaluateScriptAsync在您准备好继续之前已被标记为已完成。一旦javascript通知浏览器它应该滚动已经执行,它将被标记为已完成,而不是在浏览器在发送滚动命令后重新渲染屏幕后被标记为已完成。