You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CefSharp运行JS时如何等待页面加载完成后执行后续脚本

CefSharp 等待页面加载后执行JS脚本解决方案

你可以先封装一个通用的页面加载等待扩展方法,用于在JS执行后等待页面加载完成:

public static class CefSharpExtensions
{
    public static async Task WaitForLoad(this IWebBrowser browser, int timeoutMs = 30000)
    {
        if (!browser.IsLoading) return;
        
        var tcs = new TaskCompletionSource<bool>();
        void LoadingStateChangedHandler(object sender, LoadingStateChangedEventArgs args)
        {
            if (!args.IsLoading)
            {
                tcs.TrySetResult(true);
                browser.LoadingStateChanged -= LoadingStateChangedHandler;
            }
        }

        browser.LoadingStateChanged += LoadingStateChangedHandler;
        var timeoutTask = Task.Delay(timeoutMs);
        var completedTask = await Task.WhenAny(tcs.Task, timeoutTask);
        if (completedTask == timeoutTask)
        {
            browser.LoadingStateChanged -= LoadingStateChangedHandler;
            throw new TimeoutException("页面加载超时");
        }
    }
}

上述扩展类可以放在项目任意公共位置,引入命名空间后即可直接调用Browser.WaitForLoad()方法。

修正后的完整业务代码如下,修复了原有代码异步等待逻辑缺失、Promise语法错误、阻塞UI线程的问题:

using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using CefSharp;
using CefSharp.Wpf;

namespace WpfApp2
{
    public partial class MainWindow : Window
    {
        private string MessagesInbox;
        public MainWindow()
        {
            InitializeComponent();
        }

        // 事件处理方法改为异步签名
        private async void Browser_Loaded(object sender, RoutedEventArgs e)
        {
            // 等待浏览器初始页面加载完成
            await Browser.WaitForLoad();
            
            // 执行登录填充+点击脚本
            await Browser.EvaluateScriptAsync(@"document.getElementById('User').value = 'test'; document.getElementById('Password').value = 'password'; document.getElementById('LoginButton').click();");
            
            // 等待登录跳转后的新页面加载完成
            await Browser.WaitForLoad();
            
            // 执行后续获取数据的脚本,修正原Promise语法错误
            var test = await Browser.EvaluateScriptAsPromiseAsync(@"return new Promise(function(resolve, reject) { setTimeout(function() { var test = ''; document.querySelectorAll('.MasterAction').forEach(el => test += el.children[3].children[0].href + ', '); resolve(test); }, 2000)});");
            
            MessagesInbox = test.Result.ToString();
            MessageBox.Show(MessagesInbox);
        }
    }
}

补充说明:

  • WPF的事件处理方法使用async void是合法写法,不会产生异步泄漏问题
  • 页面加载超时默认设置为30秒,可根据实际需求调整参数
  • 原代码中的Promise逻辑未正确传参到resolve,已做修正保证可以拿到正常返回值

内容的提问来源于stack exchange,提问作者Christopher Hutton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 00:39:02