代码之家  ›  专栏  ›  技术社区  ›  rudigrobler

C尝试/捕捉恶梦

  •  3
  • rudigrobler  · 技术社区  · 15 年前

    我有一个类似代码的申请(不是我写的)

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

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

    我知道这段代码有多糟糕,但这样做是有原因的!

    我的问题是:我可以看到它在EnumerateSomeCoolHardwaredEvice()中的某个位置崩溃;但它不会被catch(…)捕获-它只会与发送报告对话框崩溃!这目前也只发生在发布版本中…他们有什么理由不让catch(…)捕获我的异常吗?

    12 回复  |  直到 15 年前
        1
  •  8
  •   Joey Gumbo    15 年前

    我的猜测是,在您的语言/框架中,您不会得到一个例外,而是 EnumerateSomeCoolHardwareDevice() 做一些奇怪的事情,只会让操作系统扼杀你的进程。请记住,硬件细节是通过Java和.NET之类的框架来抽象的,所以当你直接用硬件做某事时,你很可能依赖于非托管资源…不管哪里出了问题,都会杀了你,抓不抓。

        2
  •  7
  •   fyjham    15 年前

    一个可能的原因是 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);
            }
        }
    

    如果你运行这个应用程序,它将崩溃并烧毁,而不是像你预期的那样捕获异常。

        3
  •  3
  •   Community CDub    7 年前

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

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

        4
  •  2
  •   Alistair Evans    15 年前

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

        5
  •  2
  •   adrianm    15 年前

    你试过这个属性吗

    程序集:RuntimeCompatibility(WrapNonExceptionThrows=true)

    它应该将任何非.NET异常包装到System.Exception中,以便在代码中捕获它。

        6
  •  1
  •   Mauro    15 年前

    如果它只发生在生产计算机上而不是开发人员计算机上,那么它可能是由于DLL不匹配造成的。再次检查所有引用的DLL和框架是否是同一版本。

    其次,如果EnumerateSomeCoolHardwaredDevice()没有抛出错误,那么它将使应用程序崩溃,因为在我的经验中,异常无法恢复堆栈(或者这是我对try/catch的理解),这在我以前发生过。

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

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

        7
  •  1
  •   softveda    15 年前

    如果您在.NET版本1.1中,请使用无参数catch块,如

    catch{
    ...
    }
    

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

    同时连接到AppDomain unhandled exception 看看会发生什么。

        8
  •  0
  •   Paul Alan Taylor    15 年前

    可能会有一个尝试…在里面接住 EnumerateSomeCoolHardwareDevice() .

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

        9
  •  0
  •   user228654    15 年前

    (假设Java)错误和异常都是子类。 Throwable .如果有一个断言失败 EnumerateSomeCoolHardwareDevice() 例如,您将得到一个错误。

        10
  •  0
  •   Tamas Czinege    15 年前

    我猜是发生了堆栈溢出。.NETVM只会关闭遇到堆栈溢出的发布构建过程,不会引发任何CLR异常。该函数内部可能有一个内部try/catch,它以某种方式捕获stackoverflowException,这就是为什么它也不会在调试版本中传播到代码中的原因。

    最简单的方法是进行调试构建、附加调试程序并指示调试程序中断 之前 引发任何异常(在Visual Studio中,调试/异常并在“公共语言运行时异常”中勾选“引发”,也可能是其他异常,在cordbg.exe中勾选“捕获异常”)。

        11
  •  0
  •   Quibblesome    15 年前

    如果它崩溃得很厉害,并且正在使用serialport对象,那么很可能是因为它在某个时刻跳到了后台线程上,这时会发生异常。iirc.dataReceived事件或从串行端口获取信息时返回后台线程上的数据。如果在此例程中引发异常,则整个应用程序将被保释。

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

        12
  •  0
  •   Rob Levine    15 年前

    你看到过什么类型的异常以这种方式表现?你有他们的名单吗?

    有些异常将继续支撑调用堆栈,即使它们被捕获在catch块中,例如 ThreadAbortException .

    其他的基本上是不可处理的,例如 StackOverflowException ExecutionEngineException .

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