退出时未处理的异常

Unhandled exception on exit

我正在尝试评估 CefSharp 在 XAML/WPF 应用程序中是否适合我们。

目前,我们正在使用 MS 的 WebBrowser,它有严重的局限性。

在我们的应用程序中,我们有一个 window,它显示多个自定义控件之一,其中一个包含一个浏览器控件,用于加载包含地图的网页。

为了测试,我创建了一个自定义控件,其中包含硬编码为 http://www.google.com 的 WebBrowser。

然后我创建了第二个自定义控件,其中包含硬编码为 http://www.google.com 的 ChromiumWebBrowser。

我在代码中对任何一个浏览器控件都没有做任何事情,我只是让包装它们的用户控件可见或折叠。

但是如果我将 ChromiumWebBrowser 包含在 XAML 中,无论我是否使其可见,退出时我都会得到一个异常:

System.InvalidOperationException was unhandled
Message: An unhandled exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll
Additional information: The calling thread cannot access this object because a different thread owns it.

澄清一下,如果我的自定义控件包含这个,我不会得到异常:

<KtWpf:KorUserControl 
        x:Class="KtWpf.CEFSharpUtilityMap"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        xmlns:KtWpf="clr-namespace:KtWpf" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"
        >
    <DockPanel>
        <TextBox DockPanel.Dock="Top">CEFSharp</TextBox>
        <WebBrowser
                x:Name="mapBrowser"
                Source="http://www.google.com"
                />
    </DockPanel>
</KtWpf:KorUserControl>

如果它包含这个,我会:

<KtWpf:KorUserControl 
        x:Class="KtWpf.CEFSharpUtilityMap"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:cefSharp="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
        xmlns:KtWpf="clr-namespace:KtWpf" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"
        >
    <DockPanel>
        <TextBox DockPanel.Dock="Top">CEFSharp</TextBox>
        <cefSharp:ChromiumWebBrowser 
                x:Name="mapBrowser" 
                Address="http://www.google.com"
            />
    </DockPanel>
</KtWpf:KorUserControl>

有什么想法吗?

我正在使用来自 NuGet 的 CefSharp.Wfp 版本 49.0.0。 (还有 CefSharp.Common 和 cef.redist.x64,尽管我为 x86 构建了同样的东西。)

=== 添加调用栈 ===

>   WindowsBase.dll!System.Windows.Threading.Dispatcher.VerifyAccess()  Unknown
PresentationCore.dll!MS.Internal.Media.VisualTreeUtils.AsVisual(System.Windows.DependencyObject element, out System.Windows.Media.Visual visual, out System.Windows.Media.Media3D.Visual3D visual3D)    Unknown
PresentationCore.dll!MS.Internal.Media.VisualTreeUtils.AsNonNullVisual(System.Windows.DependencyObject element, out System.Windows.Media.Visual visual, out System.Windows.Media.Media3D.Visual3D visual3D) Unknown
PresentationCore.dll!System.Windows.Media.VisualTreeHelper.GetParent(System.Windows.DependencyObject reference) Unknown
PresentationCore.dll!System.Windows.Media.Visual.ClearTreeBits(System.Windows.DependencyObject e, System.Windows.Media.VisualFlags treeFlag, System.Windows.Media.VisualFlags nodeFlag) Unknown
PresentationCore.dll!System.Windows.Media.Visual.VisualAncestorChanged.remove(System.Windows.Media.Visual.AncestorChangedEventHandler value)    Unknown
PresentationCore.dll!System.Windows.PresentationSource.RemoveSourceChangedHandler(System.Windows.IInputElement e, System.Windows.SourceChangedEventHandler handler) Unknown
CefSharp.Wpf.dll!CefSharp.Wpf.ChromiumWebBrowser.Dispose(bool isdisposing)  Unknown
CefSharp.Wpf.dll!CefSharp.Wpf.ChromiumWebBrowser.Dispose()  Unknown
CefSharp.Core.dll!CefSharp.Cef.Shutdown()   Unknown
CefSharp.Core.dll!CefSharp.Cef.ParentProcessExitHandler(object sender, System.EventArgs e)  Unknown

我们需要做的是控制初始化和关闭。

在App.OnStartup()中:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);
    Cef.Initialize();
    ...
}

在App.OnExit():

protected override void OnExit(ExitEventArgs e)
{
    Cef.Shutdown();
    base.OnExit(e);
}