【问题标题】:Extremely Vague Exception [closed]极其模糊的异常[关闭]
【发布时间】:2013-05-18 08:22:14
【问题描述】:

我一直在从事一个使用 wunderground 的自动完成 API 的项目,但我一直遇到一个非常随机的错误。代码位于here

我得到的异常是 AccessViolationException。输入文本框时偶尔会出现。

异常信息:

using (XmlReader reader = XmlReader.Create(requestURL))

异常:抛出:“指定的注册表项不存在。” (系统.IO.IOException) 引发了 System.IO.IOException:“指定的注册表项不存在。” 时间:2013-05-18 14:55:59 线程:主线程[5672] 异常:捕获:“指定的注册表项不存在。” (系统.IO.IOException) 捕获到 System.IO.IOException:“指定的注册表项不存在。” 时间:2013-05-18 14:55:59 线程:主线程[5672]

Application.Run(new Form1());

异常:抛出:“试图读取或写入受保护的内存。这通常表明其他内存已损坏。” (System.AccessViolationException) 引发了 System.AccessViolationException:“试图读取或写入受保护的内存。这通常表明其他内存已损坏。” 时间:2013-05-18 14:55:59 线程:主线程[5672]

异常:抛出:“试图读取或写入受保护的内存。这通常表明其他内存已损坏。” (System.AccessViolationException) 引发了 System.AccessViolationException:“试图读取或写入受保护的内存。这通常表明其他内存已损坏。” 时间:2013-05-18 15:00:01 线程:主线程[4340]

我已经在 3 台不同的计算机上尝试过,但过了一段时间......总是会发生同样的错误。

【问题讨论】:

  • 我暂时不知道,但如果您可以从异常中追踪并发布堆栈跟踪,这可能会有所帮助。这将揭示错误发生的确切位置。
  • AccessViolationException 大多数时候是您正在使用的非托管组件中的错误。有时会发生此错误,因为您正在做组件不喜欢的事情,因此可能有一种解决方法。最好联系组件供应商支持。

标签: c# .net xmlreader


【解决方案1】:

我可以在 Windows 8 上重现 AccessViolation。您必须启用非托管代码调试并启用符号服务器才能查看原因,麻烦制造者是 Windows 内置的自动完成消息处理程序。通常是一段相当古怪的代码,它是通过子类化编辑控件来截取消息来实现的。调用堆栈如下所示:

shell32.dll!CAutoComplete::_StartCompletion()  + 0x4e bytes 
shell32.dll!CAutoComplete::_OnChar()  + 0x7a bytes  
shell32.dll!CAutoComplete::_EditWndProc()  - 0x6ae52 bytes  
shell32.dll!CAutoComplete::s_EditWndProc()  + 0x23 bytes    
comctl32.dll!_CallNextSubclassProc@20()  + 0x92 bytes   
comctl32.dll!_MasterSubclassProc@16()  + 0xa5 bytes 
user32.dll!_InternalCallWinProc@20()  + 0x23 bytes  
user32.dll!_UserCallWinProcCheckWow@36()  + 0xbd bytes  
user32.dll!_DispatchMessageWorker@8()  + 0xf8 bytes 
user32.dll!_DispatchMessageW@4()  + 0x10 bytes  
[Managed to Native Transition]  
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID, int reason, int pvLoopData) + 0x24d bytes    
// etc.., not interesting

由于 TextChanged 事件处理程序中的 TextBox.AutoCompleteCustomSource 属性分配,这会出错。更改该属性会有很多的副作用,它会强制重新创建编辑控制窗口,以便新的自动完成列表生效。这与子类化代码的交互非常糟糕,可能是因为它仍在使用旧的编辑控件,其窗口在 Winforms 有机会重新初始化新控件之前已被销毁或运行。

一种解决方法是等待设置属性,直到事件处理完成。这可以通过 Control.BeginInvoke() 方法优雅地完成。将属性分配更改为如下所示:

    this.BeginInvoke(new Action(() => {
        textboxInput.AutoCompleteCustomSource = autoComplete;
    }));

现在文本框的窗口被销毁并稍后重新创建,就像它正在处理 keydown 事件一样,消除了销毁窗口的痛苦。请注意重新创建窗口的效果是如何显而易见的,文本框像廉价汽车旅馆一样闪烁。我严重怀疑您是否真的想在运输程序中使用它。

【讨论】:

  • 我对您的复制项目表示赞赏,顺便说一句,您很容易为您提供帮助。
  • 这个项目是我自己感兴趣的。我想学习如何使用外部 API。我猜想我想用 AutoComplete 做什么通常只适用于本地 SQL 数据库或类似的东西。感谢您帮助我!
猜你喜欢
  • 2014-04-23
  • 1970-01-01
  • 2015-05-26
  • 2014-01-30
  • 1970-01-01
  • 2017-04-05
  • 1970-01-01
  • 2020-03-22
  • 1970-01-01
相关资源
最近更新 更多