wpf
wpf copied to clipboard
Spell Check very slow and causes UI to become unresponsive
.NET Version: I tried this with .Net Framework 4.5.2, 4.7.2, 4.8 and .Net (Core) 6.0. Windows version: Windows 11 Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes
Hi,
The spell checking is really slow in our Application (.Net 4.7.2) and causes the UI to become unresponsive and essentially unusable until the spell check is complete. This affects both the text box and the rich textbox.
To investigate this I created a simple test project with a single textbox with spelling enabled (SpellCheck.IsEnabled="True") bound to a string property. At start-up I load the string property with text and the problem is observed. Once the spell check has finished the UI becomes responsive again.
The problem seems worse the more misspelt words there are in the text and the longer the text is (tested with "Lorum Ipsum" text). It is also made worse if there are multiple text boxes/rich text boxes with spelling enabled on the same window (as is the case in our actual application).
My colleague claims to have also observed high CPU, but in my testing CPU was around 8% (laptop with Core I9 & 32GB). I wonder whether it is more to do with the UI thread being blocked.
I tried the switch: AppContext.SetSwitch(@"Switch.System.Windows.Controls.DoNotAugmentWordBreakingUsingSpeller", true); but this didn't seem to make much, if any, difference.
I know it's a completely different beast, but I did some testing with the same text in Word and of course it was very responsive. This appears similar to #3350.
This has been reported by our customers.
Thanks
@LaughingJohn Could you please provide a sample repro for this issue?
Attached. This is .Net 6.0. Same happens in .Net 4.5. I appreciate that Lorum Ipsum is a kind of worse case scenario, but this is causing issues in a real life application with normal English text.
Any news on this? We're still seeing issues..
Still seeing this issue!
The issue can still be seen with .NET9, too.
I believe that in some cases this can even cause "FailFast" crashes, though I could not reproduce this myself.
CoreCLR Version: 8.0.23.53103
.NET Version: 8.0.0
Description: The application requested process termination through System.Environment.FailFast.
Message: Nicht behebbarer Systemfehler.
Stack:
at System.Environment.FailFast(System.String)
at System.Windows.Documents.SpellerStatusTable.MarkErrorRange(System.Windows.Documents.ITextPointer, System.Windows.Documents.ITextPointer)
at System.Windows.Documents.Speller.ScanTextSegment(ISpellerSegment, System.Object)
at System.Windows.Documents.WinRTSpellerInterop.EnumTextSegments(Char[], Int32, EnumSentencesCallback, EnumTextSegmentsCallback, System.Object)
at System.Windows.Documents.Speller.ScanRange(System.Windows.Documents.ITextPointer, System.Windows.Documents.ITextPointer, Int64)
at System.Windows.Documents.Speller.OnIdle(System.Object)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef)
at System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame)
at System.Windows.Application.RunDispatcher(System.Object)
at System.Windows.Application.RunInternal(System.Windows.Window)
....