无法使 CefSharp 加载同步

Can't make CefSharp load synchronous

我有一个关闭屏幕 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 来指示我已完成?我做错了什么吗?

public static Task LoadPageAsync(IWebBrowser browser, string address = null)
{
    var tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);

    EventHandler<LoadingStateChangedEventArgs> handler = null;
    handler = (sender, args) =>
    {
        //Wait for while page to finish loading not just the first frame
        if (!args.IsLoading)
        {
            browser.LoadingStateChanged -= handler;
            //Important that the continuation runs async using TaskCreationOptions.RunContinuationsAsynchronously
            tcs.TrySetResult(true);
        }
    };

    browser.LoadingStateChanged += handler;

    if (!string.IsNullOrEmpty(address))
    {
        browser.Load(address);
    }
    return tcs.Task;
}

请注意,我使用了 LoadingStateChanged,因为它可以更好地指示整个页面何时完成加载。