简体   繁体   English

不抛出异常(在Win7中?)

[英]Exception not throwing (in Win7?)

I have application reads in data from text file. 我有应用程序读取文本文件中的数据。 Recently I realized that I should make a data checker for the data in the text file, to see if I can display/handle it correctly. 最近我意识到我应该为文本文件中的数据做一个数据检查,看看我是否能正确显示/处理它。

Basically at the moment all the checker does is see if data is in the correct format, ie double is a double, int is int, etc... And if it isn't I'm throwing an exception. 基本上目前所有检查程序都会查看数据是否格式正确,即double是double,int是int等等。如果不是,我会抛出异常。

Like so: 像这样:

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.");
        }

Which would be great. 哪个会很棒。 Except for the following: 除以下情况外:

  • I built this in Win 7 Environment in VS 2008. 我在VS 2008的Win 7环境中构建了这个。
  • I've tested in Win7/ XP 我在Win7 / XP中测试过
  • When running in Win7 - the exception does not throw. 在Win7中运行时 - 异常不会抛出。 I can even see that it should have, as I display the data it loads into a listbox in the app, but after loading the list is blank. 我甚至可以看到它应该有,因为我显示它加载到应用程序的列表框中的数据,但加载后列表是空白的。 If I step through the code line by line to the item where there is bad data, I can see the exception throw. 如果我逐行遍历代码到有坏数据的项目,我可以看到异常抛出。 But not in Debug if not debugging line by line, and not in Release either. 但是如果不是逐行调试,则不在Debug中,也不在Release中调试。
  • In XP the exception throws as expected. 在XP中,异常按预期抛出。

This is obviously a problem having the application run in a state where there is problem with the data but no indication to user and it should not have let the user get this far IF there was a problem with the data. 这显然是一个问题,如果应用程序在数据存在问题的状态下运行但没有向用户显示,并且如果数据存在问题,则不应该让用户得到这么多。

Why isn't the exception throwing in Win7? 为什么Win7中没有例外?


edit: 编辑:

I think maybe the exception is being swallowed as I only see it thrown when stepping through line by line. 我想也许这个例外被吞噬了,因为我只是看到它逐行逐行时抛出。 What is the best way to check if it is being swallowed? 检查它是否被吞下的最佳方法是什么? Just follow my apps execution and look for a Try block? 只需按照我的应用程序执行并寻找Try块? (It still doesn't exactly make sense when it throws properly in XP already, however...) (当它在XP中正常抛出时仍然没有意义,但是...)

As a bit of extra, I have a start up window with 3 buttons. 作为额外的一点,我有一个带3个按钮的启动窗口。 One is Open button. 一个是打开按钮。 From here I open the data file to process. 从这里我打开要处理的数据文件。

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

//At this point, FormLoad of all tabitems inside window1 execute, where the exception SHOULD throw. //此时,window1中所有tabitems的FormLoad执行,异常应该抛出。 And in fact when it happens, nothing is thrown but the execution jumps from the line where the exception should throw to the line below Close(); 事实上,当它发生时,没有任何东西被抛出,但执行从异常应抛出的行跳到Close()下面的行; and the next window loads but one screen out of three is empty because of the exception thrown because of the data. 并且下一个窗口加载但是由于数据引发的异常,因此三个屏幕中的一个是空的。

Close();

edit1: EDIT1:

The class where the exception is thrown is Singleton, I don't know if this has anything to do with the problem... 抛出异常的类是Singleton,我不知道这是否与问题有关...

edit2: EDIT2:

After several days further investigation, I'm still at a lost to why this is happening. 经过几天的进一步调查,我仍然不知道为什么会这样。 Addressing the questions: yes I know I should make my own custom exception class. 解决问题:是的我知道我应该创建自己的自定义异常类。 But this doesn't change what is happening here. 但这并没有改变这里发生的事情。 I cannot find a try catch higher up the stack. 我找不到尝试抓住更高的堆栈。 I have an exception handler where if an exception is thrown in the application, it Environment.Exit(1); 我有一个异常处理程序,如果在应用程序中抛出异常,它就是Environment.Exit(1); then logs the exception to text file. 然后将异常记录到文本文件中。 I have taken the exception handler out completely and yet still see the same behaviour. 我完全取消了异常处理程序,但仍然看到了相同的行为。

It is not due to regional settings problem... 这不是由于区域设置问题...

And anyway, all aside, this still does not explain why the exception is thrown as intended in XP (and the app crashes and logs exception to file) whereas in Win7 - the exception is ignored and execution continues. 无论如何,除此之外,这仍然无法解释为什么在XP中​​按预期抛出异常(并且应用程序崩溃并将异常记录到文件中),而在Win7中 - 忽略异常并继续执行。

First, you really should be throwing your own exceptions. 首先,你真的应该抛出自己的例外。 System.Exception is the top-level exception from which all exceptions inherit. System.Exception是所有异常继承的顶级异常。 Consider creating a DataFormatException, for example - and throwing that. 例如,考虑创建一个DataFormatException - 并抛出它。

Next, it sounds like you are likely catching System.Exception someone lower in the stack that is swallowing this exception. 接下来,听起来你可能正在捕获System.Exception某人在堆栈中较低的吞下这个异常。 Again, it would be ideal if you only catch System.Exception at the lowest point in the stack for that thread, and use that as a catch-all for the whole application. 同样,如果您只在该线程的堆栈中的最低点捕获System.Exception,并将其用作整个应用程序的catch-all,那将是理想的。 In other places in your code, you should catch the exceptions that expect to happen. 在代码中的其他位置,您应该捕获预期会发生的异常。 For example, the caller of your method should only trying to catch DataFormatException and ArgumentException (which you should throw if "doublevar" is null or empty). 例如,您的方法的调用者应该只尝试捕获DataFormatException和ArgumentException(如果“doublevar”为null或为空,则应该抛出)。 For example: 例如:

/// <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.");
}

Hope that helps... 希望有帮助......

I am assuming you are using tryparse here and rethrowing the exception just to demonstrate that try parse isn't working as expected... Why not try adding a Debug.Print inside you're if statement to see what you are getting. 我假设你在这里使用tryparse并重新抛出异常只是为了证明try parse没有按预期工作...为什么不尝试在if if语句中添加一个Debug.Print以查看你得到的内容。

Also, make sure this code isn't being called from another function that is wrapping this code with a try/catch block that is swallowing the exception 此外,请确保没有从另一个使用吞噬异常的try / catch块包装此代码的函数调用此代码

When you're stepping through in debug mode, you can see the exception getting thrown, right? 当您在调试模式中单步执行时,您可以看到异常被抛出,对吧? What happens after that? 之后会发生什么? That is, after the throw new Exception() line, where do you end up when you press F10? 也就是说,在throw new Exception()行之后,当你按下F10时,你最终会在哪里结束? That's where the exception is being swallowed. 这就是吞噬异常的地方。

If you end up in framework code somewhere, it means you need to manually add a try...catch yourself in the code that processes the file: 如果你最终在某个地方的框架代码中,这意味着你需要手动添加一个try ...自己捕获处理文件的代码:

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

Most likely your computers differ in their regional settings. 您的计算机很可能在区域设置上有所不同。 For example thousand/decimal separators differ between countries, eg "1,000.00" vs "1.000,00", DateTime formats differ, etc. Try using Parse/TryParse/ToString overloads which specify CultureInfo explicitly and avoid defaulting to computer's settings, perhaps by using CultureInfo.InvariantCulture . 例如,千位/小数分隔符在国家/地区之间有所不同,例如“1,000.00”与“1.000,00”, DateTime格式不同等。尝试使用Parse / TryParse / ToString重载,明确指定CultureInfo并避免默认为计算机设置,可能使用CultureInfo.InvariantCulture

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM