当.NET应用程序因System.AccessViolation异常而崩溃时,它意味着什么?

Joh*_*ith 4 .net c# forms exception

应用程序本身长度为2000行,因此在此处粘贴代码是没有意义的,特别是因为其中一个用户收到的异常没有给出关于我的代码的哪个部分导致问题的任何提示.

顺便说一句,该应用程序只是一个带有datagridview的Windows窗体,通常显示的行数不超过几百行,还有一些其他控件.在它崩溃之前,它正在非常缓慢地加载datagridview的每一行的单元格.(但没有其他用户遇到过同样的问题.)

例外文本如下.有人可以查看它并告诉我它是由我的代码出错的东西引起的,还是可能与遇到此异常的用户的特定设置不兼容?

我注意到下面的描述说内存已损坏.这是否意味着用户的计算机有坏RAM?

  ************** Exception Text **************
  System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
     at System.Drawing.SafeNativeMethods.Gdip.GdipDrawRectangleI(HandleRef graphics, HandleRef pen, Int32 x, Int32 y, Int32 width, Int32 height)
     at System.Drawing.Graphics.DrawRectangle(Pen pen, Int32 x, Int32 y, Int32 width, Int32 height)
     at System.Windows.Forms.ControlPaint.DrawFlatCheckBox(Graphics graphics, Rectangle rectangle, Color foreground, Brush background, ButtonState state)
     at System.Windows.Forms.ControlPaint.DrawFlatCheckBox(Graphics graphics, Rectangle rectangle, ButtonState state)
     at System.Windows.Forms.ControlPaint.DrawCheckBox(Graphics graphics, Int32 x, Int32 y, Int32 width, Int32 height, ButtonState state)
     at System.Windows.Forms.ControlPaint.DrawCheckBox(Graphics graphics, Rectangle rectangle, ButtonState state)
     at System.Windows.Forms.CheckedListBox.OnDrawItem(DrawItemEventArgs e)
     at System.Windows.Forms.ListBox.WmReflectDrawItem(Message& m)
     at System.Windows.Forms.ListBox.WndProc(Message& m)
     at System.Windows.Forms.CheckedListBox.WndProc(Message& m)
     at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
     at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
     at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Run Code Online (Sandbox Code Playgroud)

Dre*_*kes 5

没有更多代码,很难准确说出来.以下是一些需要注意的事项.

.NET是一个托管环境,其创建原则之一是能够在编译时验证代码.具体而言,这意味着可以对一个代码单元进行某些保证,例如:

  • 无法读取超出数组的范围
  • 无法修改函数指针
  • 无法读取/修改内存的代码段
  • 无法混淆对象引用的类型

尝试执行这些操作要么在编译时失败,要么在运行时出现异常.

您看到的例外是"不安全"代码的结果.不安全实际上有点用词不当 - 它更好地描述为"无法验证".有时,出于性能原因,有必要放弃代码的可验证性,以通过指针算法之类的东西来换取原始速度.

这个程序没有不安全的代码.

WinForms广泛使用"不安全"代码.更确切地说,你的程序集没有任何不安全的代码,但这取决于不安全的库代码.

我注意到下面的描述说内存已损坏.这是否意味着用户的计算机有坏内存?

坏内存是可能的,但不太可能.当预期的值实际存在时,内存已损坏.这可能是由于硬件故障,也是由于软件错误.此异常通常是根据我的经验中的软件错误引起的.此消息也表示内存可能已损坏.

这里的堆栈跟踪实际上可能不是很有见地,因为内存很可能在某些早期被破坏,并且只在您在此处看到的堆栈帧中检测到.

有一个平台调用user32.dll的ShowWindow函数(ShowWindow(p.MainWindowHandle,SW_SHOWDEFAULT);),但此调用发生在消息循环启动之前.

这可能是罪魁祸首.您是否尝试过使用托管的Window.Show方法?可能是您的窗口还没有处理,或者它已经改变,或者由于这个原因导致任何数量的错误.通常在本机内容上使用托管包装时尝试避免PInvoke.

遗憾的是,如果没有看到更多的代码,就不可能提供更有用的答案,但希望上面提供了一些异常的上下文,可以帮助您找出应用程序正在做什么以使WinForms进入这种状态.