部分崩溃的应用程序?如何捕获无法捕获的异常?

ytg*_*ytg 9 c# compact-framework windows-ce

我有一个用C#编写的程序,在Windows CE设备上运行(在Compact Framework上).它处理最少的用户操作(按钮点击),使用串行端口和TCP/IP通信.

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

由于我的想法不足,问题是:什么错误或异常或操作系统操作或硬件故障会导致这样的行为?

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

Abe*_*bel 10

有些例外是无法捕获的,哪些不同于.NET版本到.NET版本.并且可以捕获并记录一些异常,但无法从(内存异常)中恢复.但是,可以调试它们(这些被称为第一次机会异常,第一次机会总是用于调试器,第二次机会是代码,感谢JeroenH指出这一点).这是CodeProject上的一篇文章,解释了这个原理.

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

拥有非托管资源(串行端口)意味着您可以拥有非托管泄漏(不正确使用IDisposable+ using)和非托管异常.这些例外情况只能用一个空抓catch(即无连规范Exception,这是不是非托管异常的母公司)在try/catch块.

PS:在finally块或终结器/析构函数中引发异常时,可能会发生一些未定义的行为.此外,没有多少异常通过线程边界传播并终止所有线程.

编辑

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

另外还有的ExecutionEngineExceptionBadImageFormatException不应该在可验证代码发生,不应该被抓住.例外,如TypeLoadExceptionMissingMemberException有时能抓到,有时不是(如果链接的组件缺失,这将是很难赶上这些了,你不应该,但如果你使用反射,你应该抓住这些).

简而言之:异常应该在它们发生的线程中捕获.如果它们发生在另一个线程中,你将无法捕获异常,因为它们不会被传播(除了ThreadAbortException).您的应用程序在异常之后保持活动状态(至少,您认为),因此可以合理地假设异常不会发生在您尝试捕获它的线程中.使用Debug> Exceptions窗口,您可以选择任何异常并在代码发生时中断.

关于例外的说明

关于托管和非托管异常的补充说明.您无法捕获非托管异常catch (Exception e),因为非托管异常不会继承Exception.相反,使用空catch,它将为您捕获任何非托管异常.围绕您的应用程序和线程入口点方法进行包装,您应该能够捕获大多数可捕获的异常.