c# – 部分崩溃的应用程序?如何捕获不可限制的异常?

前端之家收集整理的这篇文章主要介绍了c# – 部分崩溃的应用程序?如何捕获不可限制的异常?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个用C#编写的程序,在 Windows CE设备上运行(在Compact Framework上).它处理最小的用户操作(按钮点击),使用串行端口和TCP / IP通信.

这个问题有时候软件会自动关闭.
后台,应用程序(或应用程序的一部分)似乎仍在运行(至少在一个记录的情况下),因为它使用串行端口,因此重新启动应用程序并没有帮助.我无法重现这个问题,因为在大多数情况下,当没有用户交互,没有串口通信和网络通信都是“我还活着”的消息时,这个软件似乎没有理由崩溃了. (我试图让它发生在调试模式下,至少知道代码中的问题在哪里,如果它是一个软件错误,但我迄今没有运气.)

由于我的想法不足,问题是:哪些错误或异常或操作系统操作或硬件故障可能会导致此类行为?

在同一类型的不同设备上看到问题,因此不应该是硬件错误. (或者我所有的硬件都有相同的错误.)异常被处理,所以它不应该是一个例外.未处理的异常也被处理,所以它也不应该是一个未处理的异常. (我的猜测是它是由StackoverflowException引起的,因为我不知道任何其他不能被捕获的异常,但是代码中没有递归,至少不会自愿,所以它不应该是一种可能性无论是.)

解决方法

很多异常不能被捕获,哪些不同于.NET版本到.NET版本.并且可以捕获并记录一些异常,但无法从(内存异常)中恢复.然而,可以调试它们(这些被称为 first chance exceptions,第一次是调试器的机会,第二次机会是代码,感谢JeroenH指出这一点).这是一个 post at CodeProject that explains this的原则.

您应该做的是在Visual Studio中选择一些您可能会发生的候选异常,并将调试器附加到正在运行的实例.

拥有非托管资源(串行端口)意味着您可以有非托管泄漏(不正确使用IDisposable)和非托管异常.这些异常只能在try / catch块中被空捕获(即,不指定甚至异常,而不是非托管异常的父级).

PS:在finally块或finalizer /析构函数中引发异常时,可能会发生一些未定义的行为.而且,不是很多异常传播通过线程边界并终止所有线程.

编辑

为了使事情更清晰一些,CLR(及其规范)定义为不可捕获的一些例外.基本上,这些都是跨线程边界的例外.这些异步异常在锁中发生时会导致状态损坏.最着名的是OutOfMemoryException,ThreadAbortException和StackOverflowException.当同步代码中出现OutOfMemoryException或StackOverflowException时,您不太可能会更正状态,并且CLR将终止您的应用程序.

另外还有ExecutionEngineException和BadImageFormatException,它不应该在可验证的代码中发生,不应该被捕获.有时候可能会捕获到TypeLoadException和MissingMemberException异常(如果链接的程序集丢失,那么很难捕获这些异常,而不应该使用,但是如果使用反射,则应该捕获这些异常).

简而言之:异常应该被捕获在它们发生的线程中.如果它们发生在另一个线程中,则不会捕获异常,因为它们不被传播(除了ThreadAbortException).您的应用程序在异常之后保持活动(至少您认为),所以假定在尝试捕获它的线程中不会发生异常是合乎逻辑的.使用Debug>例外窗口,您可以选择任何异常,并在代码发生时中断.

注意异常

关于管理和非托管例外的补充说明.您不能捕获使用catch(异常e)的非托管异常,因为非托管异常不会从Exception继承.相反,请使用空捕获,这将捕获任何非托管的异常.将其围绕您的应用程序和线程entrypoint方法,您应该能够捕获大多数可捕获的异常.

猜你在找的C#相关文章