不抛出异常(在Win7中?)

时间:2010-06-24 01:09:21

标签: c# visual-studio-2008 exception windows-7 exception-handling

我有应用程序读取文本文件中的数据。最近我意识到我应该为文本文件中的数据做一个数据检查,看看我是否能正确显示/处理它。

基本上目前所有检查器都会查看数据是否格式正确,即double是double,int是int等等......如果不是,我会抛出异常。

像这样:

private static string CheckDouble(string doublevar)
        {
            double tryParseDoubleResult;
            var tryParseDouble = double.TryParse(doublevar, out tryParseDoubleResult);

            if (tryParseDouble)
            {
                return doublevar;
            }

            throw new Exception("Invalid data found. Cannot open.");
        }

哪个会很棒。除以下情况外:

  • 我在VS 2008的Win 7环境中构建了这个。
  • 我在Win7 / XP中测试过
  • 在Win7中运行时 - 异常不会抛出。我甚至可以看到它应该有,因为我显示它加载到应用程序的列表框中的数据,但加载后列表是空白的。如果我逐行遍历代码到有坏数据的项目,我可以看到异常抛出。但是如果没有逐行调试,则不在Debug中,也不在Release中。
  • 在XP中,异常会按预期抛出。

这显然是一个问题,如果应用程序在数据出现问题的状态下运行但没有向用户显示,并且如果数据出现问题,则应该让用户不要这么做。

为什么在Win7中抛出异常?


修改

我想也许这个例外被吞噬了,因为我只是看到它逐行逐行时抛出。检查它是否被吞下的最佳方法是什么?只需按照我的应用程序执行并寻找Try块? (当它在XP中正常抛出时仍然没有意义,但是......)

作为一个额外的,我有一个带3个按钮的启动窗口。一个是打开按钮。从这里我打开要处理的数据文件。

var w = new Window1();
w.Show();

//此时,window1中所有tabitems的FormLoad都会执行,异常应抛出。事实上,当它发生时,没有任何东西被抛出,但执行从异常应抛出的行跳到Close()下面的行;并且下一个窗口加载但是由于数据引发了异常,因此三个屏幕中的一个是空的。

Close();

EDIT1:

抛出异常的类是Singleton,我不知道这是否与问题有关...

EDIT2:

经过几天的进一步调查,我仍然不知道为什么会这样。解决问题:是的我知道我应该创建自己的自定义异常类。但这并没有改变这里发生的事情。我找不到尝试抓住更高的堆栈。我有一个异常处理程序,如果在应用程序中抛出异常,它Environment.Exit(1);然后将异常记录到文本文件中。我完全取消了异常处理程序,但仍然看到了相同的行为。

这不是由于区域设置问题......

无论如何,除此之外,这仍然无法解释为什么在XP中​​按预期抛出异常(并且应用程序崩溃并将异常记录到文件中),而在Win7中 - 异常被忽略并继续执行。

4 个答案:

答案 0 :(得分:2)

首先,你真的应该抛出自己的例外。 System.Exception是所有异常继承的顶级异常。例如,考虑创建一个DataFormatException - 并抛出它。

接下来,听起来你可能正在捕获System.Exception,这是陷入此异常的堆栈中较低的人。同样,如果您只在该线程的堆栈中的最低点捕获System.Exception,并将其用作整个应用程序的catch-all,那将是理想的。在代码中的其他位置,您应该捕获预期会发生的异常。例如,您的方法的调用者应该只尝试捕获DataFormatException和ArgumentException(如果“doublevar”为null或为空,则应该抛出)。例如:

/// <summary>
/// Checks to see if the specified value is a double.
/// </summary>
/// <param name="valueToCheck">The value to check.</param>
/// <exception cref="ArgumentException">If <paramref name="valueToCheck"/>
/// is null or empty.</exception>
/// <exception cref="DataFormatException">If <paramref name="valueToCheck"/>
/// could not be parsed as a valid double.</exception>
private static double CheckDouble(string valueToCheck)
{
    if (string.IsNullOrEmpty(valueToCheck))
        throw new ArgumentException("Argument 'valueToCheck' cannot be null or empty.", "valueToCheck");

    double result;

    if (double.TryParse(valueToCheck, out result))
    {
        return result;
    }

    throw new DataFormatException("Value '" + valueToCheck + "' could not be parsed as a double.");
}

希望有帮助...

答案 1 :(得分:1)

我假设你在这里使用tryparse并重新抛出异常只是为了证明try parse没有按预期工作...为什么不尝试在if if语句中添加一个Debug.Print以查看你得到的内容。

另外,请确保没有从另一个使用吞噬异常的try / catch块包装此代码的函数调用此代码

答案 2 :(得分:1)

当您在调试模式中单步执行时,您可以看到异常被抛出,对吧?之后会发生什么?也就是说,在throw new Exception()行之后,当你按下F10时,你最终会在哪里结束?这就是吞噬异常的地方。

如果你最终在某个地方的框架代码中,这意味着你需要手动添加一个try ...在处理文件的代码中捕获自己:

void Form_Load(object sender, EventArgs e)
{
    try
    {
        ParseFile();
    }
    catch(Exception ex)
    {
        MessageBox.Show("The file was not valid: " + ex.Message);
    }
}

答案 3 :(得分:0)

您的计算机很可能在区域设置上有所不同。例如,千位/小数分隔符在不同国家/地区之间有所不同,例如“1,000.00”与“1.000,00”,DateTime格式不同等。尝试使用明确指定CultureInfo的Parse / TryParse / ToString重载并避免默认计算机的设置,可能是使用CultureInfo.InvariantCulture