近期遇到一个问题。应用使用过程中突然崩溃,查看dump发现异常信息例如以下:
UI dispatcher has encountered a problem:
无法关闭撤消单元。由于不存在已打开的单元。

   at MS.Internal.Documents.UndoManager.Close(IParentUndoUnit unit, UndoCloseAction closeAction)

at System.Windows.Documents.ImmComposition.UpdateCompositionText(FrameworkTextComposition composition, Int32 resultLength, Boolean includeResultText, ITextPointer& start, ITextPointer& end)
   at System.Windows.Documents.ImmComposition.RaiseTextInputStartEvent(FrameworkTextComposition composition, Int32 resultLength, String compositionString)
   at System.Windows.Documents.ImmComposition.OnWmImeChar(IntPtr

从dump上能够看到当时是在TextTox进行输入时突然崩溃,可能和输入法、UndoManager有关。
通过~*kb能够看到全部线程的堆栈
RetAddr           : Args to Child                                                           : Call Site
000007fe`fd491430 : 006b0073`00690064 0075006c`006f0056 005c0031`0065006d 0064006e`00690057 : ntdll!ZwWaitForMultipleObjects+0xa
00000000`773a0740 : 00000000`23489cd0 00000000`23489cc0 00000000`00000000 00000000`00000000 : KERNELBASE!WaitForMultipleObjectsEx+0xe8
000007fe`eaedc96a : 00000000`00000000 000007fe`d788a580 00000000`1d9f6020 00000000`000018f0 : kernel32!WaitForMultipleObjects+0xb0
00000000`7742b990 : 00000000`23489f40 00000000`00000000 00000000`00000001 00000000`2348b120 : SogouPY+0x41a614
00000000`77592a4f : 00000000`23489f40 00000000`00000006 0000f67a`00000000 00000000`00000001 : kernel32!UnhandledExceptionFilter+0x160
00000000`774fd863 : 000007fe`d2640000 000007fe`f7d9e336 00000000`23490000 00000000`774fd8f5 : ntdll!LdrpLogFatalUserCallbackException+0x3f
00000000`774d905d : 00000000`23490000 00000000`2348a0f8 00000000`2348a080 00000000`2348a100 : ntdll!KiUserCallbackDispatcherHandler+0x20
00000000`774c8c0f : 00000000`23490000 00000000`77326388 000056fa`00012a98 00000000`2348dfe0 : ntdll!RtlpExecuteHandlerForException+0xd
00000000`774c9208 : 00000000`2348b120 00000000`2348aaf0 00000000`00000001 00000000`00000000 : ntdll!RtlDispatchException+0x45a
000007fe`fd49b3dd : 00000000`2348b258 00000000`00000001 00000000`00000005 00000000`042b2c00 : ntdll!RtlRaiseException+0x22f
000007fe`f7bc565b : 00000000`2348b258 00000000`2348b198 00000000`050ac370 00000000`050bd478 : KERNELBASE!RaiseException+0x39
000007fe`f7ad18e7 : 00000000`042cfe08 00000000`050ac370 000007fe`d2ad5b05 00000000`005946b8 : clr!RaiseTheExceptionInternalOnly+0x28b
000007fe`d2ad5b40 : 000007fe`d26b1fe8 00000000`000000ab 00000000`005946b8 00000000`2348b900 : clr!IL_Rethrow+0x98
000007fe`f7bc6635 : 00000000`228c1b10 000007fe`d26b1fe8 00000000`00594620 00000000`228c1b10 : WindowsBase_ni+0x495b40
000007fe`f7bc6d6c : 00000000`00594620 000007fe`d2ad5b05 00000000`2348dfe0 00000000`005946b8 : clr!ExceptionTracker::CallHandler+0xc5
000007fe`f7bc6c1f : 00000000`2348dfe0 00000000`2348b740 00000000`2348d430 00000000`00000002 : clr!ExceptionTracker::CallCatchHandler+0x78
00000000`774d90dd : 00000000`2348d500 00000000`2348dfe0 00000000`00000000 00000000`2348b740 : clr!ProcessCLRException+0x2e2
从上面的dump信息能够看到当时有可能是用到搜狗输入法。
接下来我们就是要分析当时输入的是哪个字符,还是通过!dso查看当时全部的堆栈信息
0:012> ~12e !dso
OS Thread Id: 0x2080 (12)
RSP/REG          Object           Name
000000002142AD48 0000000002c94188 System.Text.UTF8Encoding
000000002142AEE0 00000000031de548 System.Windows.Threading.Dispatcher
000000002142AFF0 00000000031de880 System.Windows.Threading.DispatcherUnhandledExceptionEventArgs
000000002142B660 00000000031de548 System.Windows.Threading.Dispatcher
000000002142B678 00000000035b19b8 System.Windows.Threading.DispatcherOperationCallback
000000002142B680 00000000031dee38 MS.Win32.HwndSubclass+DispatcherOperationCallbackParameter
000000002142B6B0 00000000035b19b8 System.Windows.Threading.DispatcherOperationCallback
000000002142B6B8 00000000031de548 System.Windows.Threading.Dispatcher
000000002142B888 0000000002cd1ad0 System.RuntimeType
000000002142B980 00000000031de548 System.Windows.Threading.Dispatcher
000000002142B998 00000000035b19b8 System.Windows.Threading.DispatcherOperationCallback
000000002142B9A0 00000000031dee38 MS.Win32.HwndSubclass+DispatcherOperationCallbackParameter
000000002142B9D0 00000000035b19b8 System.Windows.Threading.DispatcherOperationCallback
000000002142B9D8 00000000031de548 System.Windows.Threading.Dispatcher
000000002142BBB0 00000000035b19b8 System.Windows.Threading.DispatcherOperationCallback
000000002142BBC8 00000000035b19b8 System.Windows.Threading.DispatcherOperationCallback
000000002142BBD0 00000000031dee38 MS.Win32.HwndSubclass+DispatcherOperationCallbackParameter
000000002142BC00 00000000035b19b8 System.Windows.Threading.DispatcherOperationCallback
000000002142BC08 00000000031de548 System.Windows.Threading.Dispatcher
000000002142C148 0000000002cd1ad0 System.RuntimeType
000000002142C280 00000000031de548 System.Windows.Threading.Dispatcher
000000002142C298 00000000035b19b8 System.Windows.Threading.DispatcherOperationCallback
000000002142C2A0 00000000031dee38 MS.Win32.HwndSubclass+DispatcherOperationCallbackParameter
000000002142C2D0 00000000035b19b8 System.Windows.Threading.DispatcherOperationCallback
000000002142C2D8 00000000031de548 System.Windows.Threading.Dispatcher
000000002142C658 0000000002cd1ad0 System.RuntimeType
000000002142CB28 0000000002cd1ad0 System.RuntimeType
000000002142CF08 000000000366af28 System.Windows.Documents.TextSelection
000000002142CF10 000000000366acb8 System.Windows.Documents.TextContainer
000000002142D058 0000000002c8ddc8 System.String    zh-CN
000000002142D078 00000000032b4d70 System.Char[]
000000002142D578 000000000366ad68 System.Windows.Documents.TextEditor
000000002142D5A0 000000000366af28 System.Windows.Documents.TextSelection
000000002142D5C8 000000000366ad68 System.Windows.Documents.TextEditor
000000002142D5E0 00000000030ee118 System.Windows.Input.InputManager
000000002142D608 000000000378e350 System.Windows.Documents.ImmComposition
000000002142D630 000000000378e350 System.Windows.Documents.ImmComposition
000000002142D640 000000000378e350 System.Windows.Documents.ImmComposition
000000002142D668 000000000510f550 System.Windows.Documents.FrameworkTextComposition
000000002142D680 000000000510f530 System.String    ,
从上面dump信息能够看出当时的string有zh-cn以及“ 。”。 能够推測当时应该是输入法当时是在中文输入状态下输入了“ 。”, 导致TextBox崩溃。
结论:
通过上述信息试着在应用上进行重现, 发现终于原因是:
先切换到英文输入法。输入字符到TextBox到最大长度,然后切换输入到中文输入法,选择搜狗输入法,然后敲入字母,然后按“,”。挂掉了。

推測是TextBox已经到了最大长度。对于搜狗输入法在中文情况“,”就是回车或者确认的意思,然后IME把这些字符扔给了控件,控件由于到了最大长度就又触发了Undo。
解决的方法:
把TextBox的UndoLimit设置为0,或者IsUndoEnabled设置为False, 两者都能够禁用Undo功能, 从而避免上述异常。

05-18 12:25