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

UWP重复开闭WebView2后JS端window.chrome.webview为空问题排查

UWP WebView2 重复开闭后 WebMessageReceived 随机失效问题

问题现象

重复打开关闭包含WebView2的UserControl后,会随机出现WebMessageReceived事件不触发的情况。此时JS端的window.chrome.webview为null,但WebView内容已正常加载,仅消息交互功能失效。问题触发时机随机,可能在第2次或第15次重开时出现,也可能完全不出现。

当前生命周期处理流程

  1. 调用UserControl构造函数
  2. UserControl.Loaded事件触发,设置WebView2.Source并调用ConfigureWebView函数
  3. ConfigureWebView实现:
private async Task ConfigureWebView()
{
    WebView2.CoreWebView2Initialized += WebView2_CoreWebView2Initialized;

    await WebView2.EnsureCoreWebView2Async();
    WebView2.CoreWebView2.OpenDevToolsWindow();
}
  1. 等待CoreWebView2Initialized事件触发
  2. 初始化事件中订阅DOMContentLoaded:
private void WebView2_CoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
{
    WebView2.CoreWebView2.DOMContentLoaded += CoreWebView2_DOMContentLoaded;
}
  1. DOMContentLoaded中订阅WebMessageReceived:
private void CoreWebView2_DOMContentLoaded(CoreWebView2 sender, CoreWebView2DOMContentLoadedEventArgs args)
{
    WebView2.WebMessageReceived += WebView2_WebMessageReceived;
}
  1. UserControl.Unloaded事件中调用DisposeWebView:
private void DisposeWebView()
{
    WebView2.Source = null;
    WebView2.WebMessageReceived -= WebView2_WebMessageReceived;
    WebView2.CoreWebView2.DOMContentLoaded -= CoreWebView2_DOMContentLoaded;
    WebView2.CoreWebView2Initialized -= WebView2_CoreWebView2Initialized;
    WebView2.Close();
    WebView2 = null;
}

问题根源分析

当前销毁流程存在以下潜在问题:

  • 未显式释放CoreWebView2实例,仅调用WebView2.Close()无法彻底清理其内部资源
  • 事件解绑顺序不合理,若CoreWebView2已被回收,后续解绑操作会无效
  • WebView2.Source = null执行时机过早,可能打断资源清理流程

修复方案

1. 优化销毁流程

调整资源清理顺序,优先处理CoreWebView2的资源释放,确保所有事件在实例可用时解绑:

private async void DisposeWebView()
{
    if (WebView2?.CoreWebView2 != null)
    {
        // 先解绑CoreWebView2及WebView2的所有事件
        WebView2.CoreWebView2.DOMContentLoaded -= CoreWebView2_DOMContentLoaded;
        WebView2.WebMessageReceived -= WebView2_WebMessageReceived;
        WebView2.CoreWebView2Initialized -= WebView2_CoreWebView2Initialized;

        // 停止当前加载并释放CoreWebView2资源
        await WebView2.CoreWebView2.StopAsync();
        WebView2.CoreWebView2.Dispose();
    }

    if (WebView2 != null)
    {
        WebView2.Source = null;
        WebView2.Close();
        WebView2 = null;
    }
}

2. 简化初始化流程

避免依赖CoreWebView2Initialized事件,直接在EnsureCoreWebView2Async完成后订阅事件,减少事件订阅遗漏的可能:

private async Task ConfigureWebView()
{
    await WebView2.EnsureCoreWebView2Async();
    
    // 直接订阅所需事件
    WebView2.CoreWebView2.DOMContentLoaded += CoreWebView2_DOMContentLoaded;
    WebView2.WebMessageReceived += WebView2_WebMessageReceived;
    
    WebView2.CoreWebView2.OpenDevToolsWindow();
}

3. 额外排查点

  • 确认UserControl的Unloaded事件始终被触发,可添加日志验证
  • 订阅CoreWebView2.ProcessFailed事件,记录进程异常信息,排查是否存在进程崩溃导致的功能失效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 18:40:36