WPF 拼写检查终结器 - 安全句柄已关闭

WPF Spell Check Finalizer - Safe Handle has been closed

我有一个针对 .NET 4.5.2 的 WPF 应用程序(但通常 运行 在 4.6.1 下)并且我已经在几个 TextBox 和 DataGridTextColumns 上启用了拼写检查。拼写检查是通过一种风格启用的,具体取决于用户选择的语言(我们目前仅支持 en)。应用程序和系统文化都设置为 en 或 en-US。我没有使用任何自定义词典。

通过以下样式启用拼写检查:

<Style TargetType="TextBox">
    <Style.Triggers>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding Source={x:Static Properties:Settings.Default}, Path=Culture}"
                           Value="en" />
                <Condition Binding="{Binding Source={x:Static diagnostics:Debugger.IsAttached}}"
                           Value="False" />
            </MultiDataTrigger.Conditions>
            <Setter Property="SpellCheck.IsEnabled"
                    Value="True" />
        </MultiDataTrigger>
    </Style.Triggers>
</Style>

(我们使用内置的ApplicationSettings对象存储最后选择的应用程序文化,并且只保存最通用的父文化。如果用户的系统设置为"en-US",我们将只存储"en" 简化事情。)

TextBox 在用于 TreeViewItems 的 DataTemplate 中定义,以防有任何区别。用户更可能编辑 TextBox 而不是 DataGrid,所以我怀疑问题与 TextBox 有关。

在 Windows 8 和 10,一些用户在拼写检查器中遇到崩溃,堆栈跟踪如下:

System.ObjectDisposedException: Safe handle has been closed
   at System.Threading.WaitHandle.WaitOneNative(SafeHandle waitableSafeHandle, UInt32 millisecondsTimeout, Boolean hasThreadAffinity, Boolean exitContext)
   at System.Threading.WaitHandle.InternalWaitOne(SafeHandle waitableSafeHandle, Int64 millisecondsTimeout, Boolean hasThreadAffinity, Boolean exitContext)
   at System.Threading.WaitHandle.WaitOne(Int32 millisecondsTimeout, Boolean exitContext)
   at System.Windows.Documents.WinRTSpellerInterop.ClearDictionaries(Boolean isDisposeOrFinalize)
   at System.Windows.Documents.WinRTSpellerInterop.Dispose(Boolean disposing)
   at System.Windows.Documents.WinRTSpellerInterop.Finalize()

我搜索了 Google、Whosebug 和 MSDN,但找不到任何关于此问题的参考资料。我不知道我的用户正在做什么来触发这个案例,而且我自己也无法重现它。我的日志表明他们在发生这种情况时没有编辑启用拼写检查的字段(事实上,他们所做的最后一次编辑是在异常发生前至少一两分钟)。有人有什么想法吗?

此问题已在 .NET 4.7 中得到解决(请参阅 Runtime Changes 页面上的“WPF 拼写检查器”条目)。请注意,NET 4.7 不会安装在 Windows 11 月 10 日更新或更早版本。但是,大多数 Windows 10 位用户现在应该已经在使用周年更新了。

Starting with the .NET Framework 4.6.1, the spellchecker in WPF applications occasionally throws an ObjectDisposedException during application shutdown.

In the .NET Framework 4.7, the exception is handled gracefully by the runtime, thus ensuring that applications are no longer adversely affected. It should be noted that occasional first-chance exceptions continue to be observed in applications running under a debugger.