【问题标题】:VS2010 did not break debug on static constructor exceptionVS2010 没有中断对静态构造函数异常的调试
【发布时间】:2012-03-02 11:40:27
【问题描述】:

我有一个带有单个 Editor 类(继承自 Form)的 Windows 窗体应用程序。

public partial class Editor : Form
{
    public Editor()
    {
        InitializeComponent();

        Load += Editor_Load;
    }

    private void Editor_Load(object sender, EventArgs e)
    {
        cmbConnections.DataSource = ConnectionManager.Connections;
        cmbConnections.Visible = false;
    }

}

除了设计器生成的代码之外,这是表单的唯一代码(仅包含一个组合框 (cmbConnections)。

ConnectionManager 类是具有静态构造函数的静态类。它的构造函数进行一些初始化,然后测试一些临界条件。如果满足条件,构造函数会抛出异常。但是,此异常不会在 Visual Studio 2010 中的调试模式中中断。为了对此进行测试,我仅将 throw new Exception() 放入 ConnectionManager 的静态构造函数中。 ConnectionManager 被使用并因此在 Editor_Load 事件处理程序中初始化(第一次)。调用静态构造函数并抛出异常(仅在输出窗口中可见)。正如预期的那样,Editor_Load 事件处理程序 (cmbConnections.Visible = false;) 的其余部分未执行。

但我不明白的是为什么我的VS2010会吞下异常?它没有破坏调试。它没有包含在任何 try/catch 块中。它继续在主窗口中执行程序。看起来好像Editor_Load 是在另一个线程上执行的。

我可以在输出窗口中看到消息:

Editor.exe 中出现“System.InvalidOperationException”类型的第一次机会异常

Editor.exe 中出现“System.TypeInitializationException”类型的第一次机会异常

但在调试模式下执行并没有中断。

以下是我认为可能会影响此行为的一些选项:

项目属性->构建->常规->优化代码未选中。

Tools->Options->Debugging->General-> Enable Just My Code is CHECKED.

在异常设置中,“用户未处理”的复选框是选中的。

我错过了什么吗?这种行为正常吗?我认为 VS2010 会抛出任何未处理的异常。而这里这个是未处理的,仍然没有破坏。

【问题讨论】:

  • 你忘了说你有一个 64 位操作系统。糟糕的问题,很容易解决:项目 + 属性,构建选项卡,将平台目标从 x86 更改为 AnyCPU。
  • 我还不能在我的 x64 系统(我昨天在这个系统上开发)上检查这个。但是,我在 x86 系统上尝试了相同的解决方案,它确实破坏了 VS2010。所以我想你的评论可能是正确的。我建议您将此作为答案发布。因为所有其他答案都包含与问题无关的信息,而只是解释了 VS2010 异常处理的工作原理。我的问题是关于为什么 VS2010 的行为超出了它自己的标准——我猜你已经回答了——这是 x64 系统上的某种错误。我会尽快在 x64 上进行测试以确认。
  • 虽然“重复”的问题涉及表单构造函数,但我的问题涉及静态构造函数。解决方案可能相同,但问题不同。但是,现在我想知道这里的模式是什么——它会吞下哪些异常,而不会吞下哪些异常。这确实是一个奇怪的错误。

标签: c# visual-studio-2010 exception-handling static-constructor swallowed-exceptions


【解决方案1】:

我认为您需要在“异常”对话框 (Ctrl-Alt-E) 中启用“抛出”托管 (.NET) 异常。1

为避免许多虚假(已处理)异常,我通常会尝试靠近将运行初始化程序的位置,然后在继续之前选中该复选框。

另外,如果有加载器异常,一定要检查嵌套的内部异常或异常中的加载器信息:异常本身通常没有那么丰富的信息。为了找出实际的错误,我经常不得不挖掘 2 层或更多层的包装异常。


1 我只能猜测 为什么;我的感觉是静态类型初始化器不被认为是确定性运行的(很多事情都可以触发它并且顺序通常是未定义的;它只是保证一个类型的静态构造函数在它被使用之前已经运行了 em>,但它几乎可以在代码中的任何位置使用,而无需您知道或明确触发)。

因此,运行时很难确定它是否“由用户代码处理”(用户不应该期望处理它,因为它不知道 - 确定性 - when初始化程序将运行)。

不过,这是我的猜测。

【讨论】:

    猜你喜欢
    • 2011-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    相关资源
    最近更新 更多