代码之家  ›  专栏  ›  技术社区  ›  Jared Updike

跨treeview.Nodes.Add/treeview\u AfterSelect事件边界捕获异常

  •  1
  • Jared Updike  · 技术社区  · 16 年前

    在我的WinForms程序中有一个地方抛出了MyOwnException。

    void CodeThatThrowsMyOwnException()
    {
        ...
        throw new MyOwnException("Deep Inside");
        ...
    }
    

    try
    {
        CodeThatThrowsMyOwnException();
    }
    catch (MyOwnException moe)
    {
        MessageBox.Show("Hit this point in the code! Hurray!");
    }
    MessageBox.Show("Later, alligator.");
    

    在同事的计算机上(像我一样运行VS2008SP1)会显示对话框。在我的电脑上,它从不捕捉异常,也不显示对话框。当我在抛出异常的代码行的代码(codethathrowsmyownexception)的深处放置一个断点时,它会命中该行的断点。如果我按F5(调试>运行)它跳过了我的捕获块并显示“稍后,鳄鱼”消息。

    实际粘贴“void codethathatthrowsmoownexception(){throw new MyOwnException(“Shallow”);}”在我的代码中编写代码(而不是调用真正的代码),并直接调用“CodeThrowsMyOwnException();”但是,try块中的get会在catch块中显示消息。

    据我所知,我没有创建任何线程,我已经查找了try{}catch{}块,这些块捕获所有异常,但在涉及的项目中找不到任何异常(如果它们在那里,为什么这个catch块仍然在我同事的机器上工作?)

    奇怪的是,双击可执行文件来运行我的代码会在我的机器上和我同事的机器上产生一个未处理的异常。这条线索让我尝试了以下方法:

    当我在代码深处的throw MyOwnException(“Deep Inside”)行放置断点时,调用堆栈在异常处理程序和调用“throw MyOwnException(“Deep Inside”)的位置之间包含一行“[External code]”。如果我将try/catch MyOwnException块放在远离抛出的地方(但在[External Code]的这一边,我仍然可以捕获异常,无论我将try-catch块放在何处(在函数链的相关部分周围):

    try
    {
        CodeChain(...);
    }
    catch (DrawException de)
    {
        MessageBox.Show("Hurray!"); // being executed, but only on the 'throw' side of the [External Code] part of the call stack
    }
    

    try
    {
        treeview.Nodes.Add(treeNode); // triggers the aforementioned chain of code with MyOwnException thrown
    }
    catch (DrawException de) // no matter what I do, this will not handle my cursed MyOwnException
    {
        MessageBox.Show("Hurray!"); // not being executed
    }
    

    我有一种假设,他的调试器正在神奇地跨线程边界(或跨外部代码,即Windows GUI事件)在调试器中提升异常,而在其他三种情况下(我的调试器(不带64位扩展名)以及任何一台计算机从windows资源管理器运行EXE时,都会出现异常),该线程上的异常确实未经处理。

    那么如何捕捉这个异常呢?重新设计我的整个系统以避免使用treeview.AfterSelect?显然我不明白例外的局限性。

    潜在问题?

    • 我有一个代表在那里保持我的系统模块化和可重用。异常是否可以“通过”一个委托,跨越模块边界抛出?

    我把它用在自动测试装置上。我需要通过重放动作脚本(文本文件)来修复复杂GUI系统中一些非常棘手的逻辑/算法错误,这些脚本可以发现这些异常情况并缩小问题范围(在我的程序中,在重写或重构设计方面,可能没有很好的解决方法:我需要在这个QA阶段捕获这些异常,在发布之前修复bug(困难的算法特殊情况),这样我就不会让我的用户受到这样的bug软件的影响。我并不是为了好玩而对外来控制流使用异常(参见Int32.Parse)

    1 回复  |  直到 16 年前
        1
  •  1
  •   msergeant    16 年前

    树视图将被称为 最

    如果AfterSelect处理程序出于某种原因要抛出异常,则不能依赖调用代码来处理这些异常。否则,调用AfterSelect的任何其他方式都可能导致未处理的异常。