UWP重复开闭WebView2后JS端window.chrome.webview为空问题排查
UWP WebView2 重复开闭后 WebMessageReceived 随机失效问题
问题现象
重复打开关闭包含WebView2的UserControl后,会随机出现WebMessageReceived事件不触发的情况。此时JS端的window.chrome.webview为null,但WebView内容已正常加载,仅消息交互功能失效。问题触发时机随机,可能在第2次或第15次重开时出现,也可能完全不出现。
当前生命周期处理流程
- 调用UserControl构造函数
- UserControl.Loaded事件触发,设置WebView2.Source并调用
ConfigureWebView函数 ConfigureWebView实现:
private async Task ConfigureWebView() { WebView2.CoreWebView2Initialized += WebView2_CoreWebView2Initialized; await WebView2.EnsureCoreWebView2Async(); WebView2.CoreWebView2.OpenDevToolsWindow(); }
- 等待
CoreWebView2Initialized事件触发 - 初始化事件中订阅
DOMContentLoaded:
private void WebView2_CoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args) { WebView2.CoreWebView2.DOMContentLoaded += CoreWebView2_DOMContentLoaded; }
DOMContentLoaded中订阅WebMessageReceived:
private void CoreWebView2_DOMContentLoaded(CoreWebView2 sender, CoreWebView2DOMContentLoadedEventArgs args) { WebView2.WebMessageReceived += WebView2_WebMessageReceived; }
- 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
相关产品推荐
相关产品推荐

