手动实例化显示MainWindow致WPF Blazor运行时抛出异常
解决WPF Blazor中手动显示窗口后调用app.Run()触发的EnsureCoreWebView2Async错误
问题场景
在WPF Blazor项目中,若按以下顺序执行代码:
- 实例化
App并初始化组件 - 实例化
MainWindow并调用window.Show() - 调用
app.Run()启动应用事件循环
会抛出错误:
EnsureCoreWebView2Async cannot be used before the application's event loop has started running.
原因分析
BlazorWebView依赖WebView2控件,而WebView2的EnsureCoreWebView2Async方法要求WPF应用的事件循环必须处于运行状态。当前代码中window.Show()先于app.Run()执行,此时事件循环尚未启动,WebView2在初始化时会触发上述错误。
有效解决方案
方案一:延迟BlazorWebView初始化至事件循环启动后
修改MainWindow.xaml.cs,将服务初始化和BlazorWebView配置逻辑移至Window.Loaded事件中,确保在事件循环启动后再执行:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private async void Window_Loaded(object sender, RoutedEventArgs e) { await Dispatcher.InvokeAsync(() => { // 构建Blazor服务集合 var serviceCollection = new ServiceCollection(); serviceCollection.AddWpfBlazorWebView(); var serviceProvider = serviceCollection.BuildServiceProvider(); // 配置BlazorWebView webView.Services = serviceProvider; webView.HostPage = "wwwroot/index.html"; webView.RootComponents.Add(new RootComponent("#app", typeof(Counter))); // 将服务加入资源(若XAML中需要绑定) Resources.Add("services", serviceProvider); }); } }
App.xaml.cs保持原有逻辑即可,因为Window.Loaded事件会在app.Run()启动事件循环后触发。
方案二:通过Dispatcher延迟窗口显示至事件循环启动
修改App.xaml.cs,先启动事件循环,再通过Dispatcher异步显示窗口,确保窗口实例化和WebView2初始化时事件循环已运行:
[STAThread] public static void Main() { var app = new App(); app.InitializeComponent(); // 事件循环启动后再显示窗口 app.Dispatcher.InvokeAsync(() => { var window = new MainWindow(); window.Show(); }); app.Run(); }
此时MainWindow.xaml.cs可保持原有构造函数逻辑,无需额外修改。
为什么直接调用EnsureCoreWebView2Async无效?
直接在窗口构造函数或window.Show()后调用EnsureCoreWebView2Async(null)无法解决问题,因为此时WPF的事件循环尚未启动,WebView2底层依赖的消息循环还未建立,仍会触发错误。
内容的提问来源于stack exchange,提问作者Mahdi
相关产品推荐
相关产品推荐

