我有一个关闭屏幕ChromiumWebBrowser
,用于在页面上运行一些JS并返回结果。
Load方法是同步的,但我不能运行JS代码,直到引发FrameLoadEnd事件,这意味着或我的目的Load是一个以FrameLoadEnd事件结束的异步方法。
为了使我的代码更清晰,我尝试创建一个扩展方法,允许我等待页面加载await
而不是注册到事件。但是当我在TaskCompletionSource中使用这个方法时,在页面加载后应该运行的javascript没有被加载,但是当使用AutoResetEvent
并等待它时代码确实有效。
此代码无效:
public static Task LoadPageAsync(this IWebBrowser browser, string address)
{
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
browser.FrameLoadEnd += (sender, args) =>
{
if (args.IsMainFrame)
{
tcs.TrySetResult(true);
}
};
browser.Load(address);
return tcs.Task;
}
这样做:
public static AutoResetEvent LoadPageAsync(this IWebBrowser browser, string address)
{
AutoResetEvent are = new AutoResetEvent(false);
browser.FrameLoadEnd += (sender, args) =>
{
if (args.IsMainFrame)
{
are.Set();
}
};
browser.Load(address);
return are;
}
这是主叫代码:
await _browser.LoadPageAsync("Some web address");
LoadScripts();
DoJsThing();
GetJsData();
他们做同样的事情,但我觉得返回任务时函数的意图要比返回AutoResetEvent时更清晰。
为什么我不能使用TaskCompletionSource来表示我已完成?我做错了吗?
答案 0 :(得分:5)
这是一个基本示例https://gist.github.com/amaitland/40394439ddefdf4e66b7
注意我使用了NavStateChanged
,因为它可以更好地指示整个网页何时完成加载。