C#尝试/捕捉噩梦

时间:2009-12-10 09:34:57

标签: c# exception-handling

我有一个类似代码的应用程序(不是我写的)

try
{
    EnumerateSomeCoolHardwareDevice();
}
catch (Exception ex)
{

} 

更新 - 这是.NET C#& EnumerateSomeCoolHardwareDevice()正在使用SerialPort?

我知道这段代码有多糟糕,但它有点像这样的原因!

我的问题:我可以看到它在EnumerateSomeCoolHardwareDevice()中的某处崩溃;但它没有被Catch捕获(...) - 它只是与发送报告对话框崩溃了!这也只发生在发布版本中...他们的任何理由为什么我的异常不会被catch(...)捕获?

12 个答案:

答案 0 :(得分:8)

我的猜测是你没有在你的语言/框架中得到异常,而是EnumerateSomeCoolHardwareDevice()做了一些奇怪的事情,只会导致操作系统终止你的进程。请记住,硬件细节是由Java和.NET等框架抽象出来的,所以每当你直接用硬件做事时,你可能都依赖于非托管资源......无论出现什么问题都可以杀死你,抓住或不捕获。

答案 1 :(得分:7)

一个可能的原因是EnumerateSomeCoolHardwareDevice()函数使用线程。如果在线程中抛出异常并且未在其线程内处理,那么它可能会使应用程序崩溃。这个简单的应用程序可以证明我的意思:

    public static void testThread()
    {
        throw new Exception("oh god it's broken");
    }

    static void Main(string[] args)
    {
        try
        {
            Thread thread = new Thread(testThread);
            thread.Start();
            Console.ReadKey(); //Just to make sure we don't get out of the try-catch too soon
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

如果您运行该应用程序将崩溃并刻录,而不是像您期望的那样捕获异常。

答案 2 :(得分:3)

在.NET中catch (Exception ex)只会捕获.NET异常,而不是本机异常。

question (catching native exceptions in C#)可能会有所帮助。

答案 3 :(得分:2)

假设.NET,如果EnumerateSomeCoolHardwareDevice通过PInvoke使用Win32方法(访问硬件)并发生错误,则大多数Native方法都会返回错误代码。如果没有处理该错误代码,并且无论如何都要调用另一个本机方法(可能是来自失败调用的空出参数),严重的本机错误(例如错误的内存访问或类似的东西)可能导致程序直接崩溃,没有异常抛出。

答案 4 :(得分:2)

您是否尝试过该属性

程序集:RuntimeCompatibility(WrapNonExceptionThrows = true)

这应该将任何非.Net异常包装到System.Exception中,以便它将被捕获到您的代码中。

答案 5 :(得分:1)

如果它只发生在生产机器而不是开发机器上,则可能是DLL不匹配。仔细检查所有引用的DLL和框架是否是相同的版本。

其次,如果EnumerateSomeCoolHardwareDevice()没有抛出错误,那么它会使应用程序崩溃,因为在我的经验中,异常无法重新获得堆栈(或者我对try / catches的理解)以前发生过我。

最后,微软错误报告通常允许您检查将发送给MS的内容,这可以让您查看错误发生的位置和原因(假设其中包含可读信息)。

检查事件查看器,因为错误也应该记录在那里,并且通常提供有关错误的宝贵详细信息来源,并且通过挖掘那里列出的错误,您应该能够跟踪故障。

答案 6 :(得分:1)

如果你在.Net 1.1版中,请使用no参数catch块,如

catch{
...
}

在.Net 2.0之前,可能存在未从System.Exception派生的本机异常。

同时挂钩到appdomain unhandled exception事件,看看会发生什么。

答案 7 :(得分:0)

EnumerateSomeCoolHardwareDevice()内可能有一个try..catch。

如果在那里捕获并处理异常,除非再次抛出异常,否则不会命中外部异常。

答案 8 :(得分:0)

(假设Java)Error和Exception都是Throwable的子类。例如,如果EnumerateSomeCoolHardwareDevice()中的断言失败,您将收到错误。

答案 9 :(得分:0)

我的猜测是发生堆栈溢出。 .NET VM只关闭遇到堆栈溢出的Release构建过程,不会抛出CLR异常。在该函数中可能存在内部try / catch,它以某种方式捕获StackOverflowException,这就是为什么它不会传播到Debug构建中的代码。

找出正在发生的事情的最简单方法是进行调试构建,附加调试器并指示调试器在抛出任何异常之前中断(在Visual Studio,Debug / Exceptions和tick中) “抛出”“公共语言运行时异常”以及可能还有其他一些,在cordbg.exe“catch exception”中

答案 10 :(得分:0)

如果它疯狂地崩溃并且正在使用SerialPort对象,那么可能是因为它在某些时候会跳到后台线程并且在这里发生异常。 IIRC .DataReceived事件或者您从串行端口获取信息返回后台线程上的数据。如果在此例程中抛出异常,则整个应用程序将保释。

找到后台线程并对其进行一些异常处理。

答案 11 :(得分:0)

您看到过哪种类型的例外行为?你有他们的清单吗?

有些异常会继续调用调用堆栈,即使它们已经被捕获,例如ThreadAbortException

其他基本上是不可处理的,例如StackOverflowExceptionExecutionEngineException

如果是其中之一(或其他一些我可能错过的),那么行为可能与预期的一样。如果是其他人,则需要更深入了解更多信息。