WPF MVVM中CefSharp的LoadingStateChanged事件线程访问异常解决
解决WPF+CefSharp MVVM模式下LoadingStateChanged事件跨线程访问错误
错误原因
CefSharp的LoadingStateChanged事件默认在非UI线程触发,而WPF的System.Windows.Interactivity.EventTrigger执行InvokeCommandAction时,会访问WPF依赖属性(比如Actions),这类属性要求必须在UI线程操作,直接绑定Command就会抛出线程访问异常。
解决方案
方案1:让CefSharp事件在UI线程触发(推荐)
CefSharp WPF版支持配置事件触发线程,初始化时开启WpfRenderingEnabled即可让UI相关事件直接在UI线程触发,原代码无需改动:
// 应用启动阶段初始化Cef var settings = new CefSettings { WpfRenderingEnabled = true // 强制CefSharp的UI事件在UI线程触发 }; if (!Cef.IsInitialized) { Cef.Initialize(settings); }
方案2:ViewModel中使用UI线程Dispatcher
如果无法修改Cef初始化配置,需要明确切换到UI线程执行逻辑。注意不能用Dispatcher.CurrentDispatcher(它取当前线程的Dispatcher,可能是后台线程),要传入UI线程的Dispatcher:
1. 改造ViewModel
public ICommand LoadingStateChangedCmd { get; set; } private readonly Dispatcher _uiDispatcher; public HomeViewModel(Dispatcher uiDispatcher) { _uiDispatcher = uiDispatcher; LoadingStateChangedCmd = new CommunityToolkitInput.RelayCommand<LoadingStateChangedEventArgs>(LoadingStateChanged); } public void LoadingStateChanged(LoadingStateChangedEventArgs args) { _uiDispatcher.Invoke(() => { if (!args.IsLoading) { // 写入加载完成后的业务逻辑 } }); }
2. View构造时传入UI线程Dispatcher
// HomeControl.xaml.cs public HomeControl() { InitializeComponent(); DataContext = new HomeViewModel(Dispatcher); }
方案3:View后台订阅事件后转发给ViewModel
放弃XAML中的EventTrigger,直接在View后台处理事件,切换线程后调用ViewModel命令:
1. HomeControl.xaml.cs
public HomeControl() { InitializeComponent(); Loaded += HomeControl_Loaded; } private void HomeControl_Loaded(object sender, RoutedEventArgs e) { if (DataContext is HomeViewModel vm) { var browser = (ChromiumWebBrowser)sender; browser.LoadingStateChanged += (s, args) => { Dispatcher.Invoke(() => vm.LoadingStateChangedCmd.Execute(args)); }; } }
2. 移除XAML中的EventTrigger
修改后的HomeControl.xaml:
<wpf:ChromiumWebBrowser WebBrowser="{Binding WebBrowser, Mode=OneWayToSource}" Address="{Binding Address, Mode=OneWay}" />
关键注意点
- 不要用
Dispatcher.CurrentDispatcher做跨线程切换,它返回的是当前线程的Dispatcher,若当前是后台线程,无法操作UI元素。 - CefSharp的多数回调事件默认在后台线程触发,所有涉及UI的操作必须切换到UI线程执行。
内容的提问来源于stack exchange,提问作者RGS
相关产品推荐
相关产品推荐

