【问题标题】:Why isn't my error being caught?为什么我的错误没有被捕获?
【发布时间】:2012-11-11 11:39:31
【问题描述】:

我有一个包含 Phone 对象的类。

电话是虚拟电话,在我的类的构造函数中,我传入了我希望连接的虚拟电话的 IP 地址和端口。

在构造函数中,然后我运行一个名为Connect 的方法。在 Connect 方法中,我从电话的 IP 地址/端口组合中实例化一个 IPEndPoint 对象,然后实例化一个 Socket 对象,然后运行 Socket 对象的 Connect 方法,传入我的 IPEndPoint 作为参数。

如果电话服务器没有为特定电话(不是我的工作)正确配置,则连接被拒绝,并抛出 SocketException。我正在尝试捕捉这个异常。

这是一个 Windows 窗体应用程序。在 Form 对象的范围内,但在任何构造函数/方法的范围之外,我将手机作为未实例化的私有字段,就像这样(iPhone 是我手机使用的接口):

private IPhone _phone;

我有一个名为 SetupPhone 的方法,我在这里实例化我的手机对象,并试图在此处捕获异常:

private void SetupPhone()
{
    try
    {
        _phone = new Phone(AgentDetails.IPAddress, AgentDetails.Port);
    }
    catch(SocketException ex)
    {
        Log.LogException("Error mapping phone to port", ex);
        ShowBaloonTip("An error occured starting CTI. Please select your name from the list to try again", ToolTipIcon.Error);

        ChangeUser();
        return;
    }

    //Subscribe to Phone events here
}

这里是电话对象的构造函数:

public Phone(string ipAddress, int port, string password = "FooBar")
{
    Connect(ipAddress, port, password);
}

这里是 Connect 方法:

public void Connect(string ipAddress, int port, string password)
{
    _phone = new IPEndPoint(IPAddress.Parse(ipAddress), port);
    _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);

    _socket.Connect(_phone);

    //Redacted
}

在未正确配置的手机上,我的 SocketException 如下所示:

我是否认为对象构造函数中运行的任何方法引发的任何异常都应该被放置在该对象实例化周围的 try/catch 块安全地捕获?还是不是这样?我想捕捉实例化我的对象时可能发生的任何错误,这不可能吗?

【问题讨论】:

  • 您是否尝试过捕获异常以查看会发生什么?
  • @activwerx 是的,我试过捕捉异常,同样的事情发生了。
  • 您是否在其他地方处理异常?也许它被抓到了更高的水平或什么?
  • Nesim 解决了它,我不久前更改了我的 VS 异常设置,因此我可以调试在其他线程上抛出的异常,这就是现在导致我的问题的原因!

标签: c# error-handling


【解决方案1】:

http://www.blackwasp.co.uk/VSBreakOnException.aspx

在调试模式下运行程序时,使用 Visual Studio 的调试器, 遇到异常,默认行为是暂停 除非错误在 try / catch 块中处理,否则执行。这个 可以针对每种异常类型修改行为。

调试模式异常

当您在调试模式下执行软件时,Visual Studio 会做出反应 与抛出的异常不同,具体取决于异常是否 在 try / catch / finally 块中处理或未处理。什么时候 使用默认配置,未处理的异常会导致 程序暂停并显示异常详细信息。已处理 异常不会导致程序停止。你可以看到这个 在调试模式下执行以下代码。虽然一个 尝试除法时抛出 DivideByZeroException, 程序继续。如果你注释掉 try and catch,异常 停止执行。

try
{
    int i = 0;
    int j = 1;
    Console.WriteLine(j / i);
}
catch
{
    Console.WriteLine("Caught an exception");
}
Console.ReadLine();

这种行为在大多数情况下都很有用。然而,有时你 即使未处理,也会希望忽略特定类型的异常, 或中断通常会被忽略的已处理异常。你 可以使用“例外”对话框来控制这一点,该对话框可以查看 通过从调试菜单中选择“例外”或按 Ctrl-Alt-E。

对话框的主要区域显示异常类型列表 树状结构。树的分支可以展开以显示 各种异常组和每个异常中的各个类型 类别。每个例外和组显示两个复选框。如果 勾选“Thrown”复选框,程序将在 选定的例外,或选定的一组例外,是 遭遇。这包括已处理的异常。如果 勾选“用户未处理”复选框,只有在 异常未处理。要尝试这些选项,请找到 树结构中的 DivideByZeroException 类型。查找异常 快速,单击查找按钮并输入项目名称的一部分 你正在寻找。将找到第一个匹配项。如果这 不是想要的异常,点击Find Next按钮循环 通过比赛。找到 DivideByZeroException 后,检查 适当的“投掷”选项。如果您运行示例程序,您 将看到程序在处理的异常上停止。

全部重置

“例外”对话框中还有一些其他选项 值得注意。其中第一个是“全部重置”按钮。如果你 已更改对话框中的选项以帮助调试您的 应用程序,您可以将所有选项重置为原始选项 单击此按钮进行设置。

配置自定义例外

如果你定义了你自己的异常类型继承 Exception 类或其子类之一的功能,您 不妨使用对话框对其进行配置。因为它不会是 标准异常类型,默认不会出现在列表中。 但是,您可以通过单击添加按钮并提供 细节。对于 .NET 异常,您应该确保选择 下拉列表中的“公共语言运行时异常”选项。 然后,您应该提供异常的完全限定名称 班级。例如,“MyNamespace.MyException”。

【讨论】:

  • 谢谢内西姆!不久前我更改了我的 VS 异常设置,因为我无法捕获其他线程上抛出的异常。这就是导致我现在出现问题的原因。将它们改回来,我的程序按预期运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-16
  • 2012-01-22
  • 1970-01-01
相关资源
最近更新 更多