3 Stimmen

Ausnahme wird nicht ausgelöst (in Win7?)

Ich habe eine Anwendung, die Daten aus einer Textdatei einliest. Kürzlich habe ich erkannt, dass ich einen Daten-Checker für die Daten in der Textdatei machen sollte, um zu sehen, ob ich sie richtig anzeigen/behandeln kann.

Im Grunde im Moment ist alles, was der Checker tut, zu sehen, wenn Daten im richtigen Format, d.h. double ist ein Double, int ist int, etc... Und wenn das nicht der Fall ist, werfe ich eine Ausnahme.

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

Das wäre großartig. Bis auf das Folgende:

  • Ich habe dies in Win 7 Umgebung in VS 2008 gebaut.
  • Ich habe unter Win7/XP getestet
  • Bei der Ausführung in Win7 - die Ausnahme nicht auslösen. Ich kann sogar sehen, dass es haben sollte, wie ich die Daten anzeigen, die es in ein Listenfeld in der App lädt, aber nach dem Laden der Liste ist leer. Wenn ich den Code Zeile für Zeile bis zu dem Punkt durchlaufe, an dem die Daten fehlerhaft sind, kann ich sehen, dass die Ausnahme ausgelöst wird. Aber nicht in Debug, wenn ich nicht Zeile für Zeile debugge, und auch nicht in Release.
  • In XP wird die Ausnahme wie erwartet ausgelöst.

Es ist offensichtlich ein Problem, dass die Anwendung in einem Zustand läuft, in dem es ein Problem mit den Daten gibt, aber keine Anzeige für den Benutzer, und es sollte den Benutzer nicht so weit kommen lassen, WENN es ein Problem mit den Daten gab.

Warum wird die Ausnahme in Win7 nicht ausgelöst?


bearbeiten:

Ich denke, dass die Ausnahme vielleicht verschluckt wird, da ich sie nur sehe, wenn ich Zeile für Zeile durchlaufe. Was ist der beste Weg zu überprüfen, ob es verschluckt wird? Folgen Sie einfach meine Anwendungen Ausführung und suchen Sie nach einem Try-Block? (Es macht immer noch nicht genau Sinn, wenn es richtig in XP wirft bereits, jedoch...)

Als kleines Extra habe ich ein Startfenster mit 3 Schaltflächen. Eine davon ist die Schaltfläche Öffnen. Von hier aus öffne ich die zu verarbeitende Datendatei.

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

//Zu diesem Zeitpunkt wird FormLoad aller Tabitems in window1 ausgeführt, wobei die Ausnahme ausgelöst werden MUSS. Und tatsächlich, wenn es passiert, wird nichts ausgelöst, sondern die Ausführung springt von der Zeile, in der die Ausnahme ausgelöst werden sollte, zur Zeile unter Close(); und das nächste Fenster wird geladen, aber einer von drei Bildschirmen ist aufgrund der Ausnahme, die wegen der Daten ausgelöst wurde, leer.

Close();

edit1:

Die Klasse, in der die Ausnahme ausgelöst wird, ist Singleton, ich weiß nicht, ob dies etwas mit dem Problem zu tun hat...

edit2:

Nach mehreren Tagen weiterer Nachforschungen bin ich immer noch ratlos, warum dies geschieht. Adressierung der Fragen: Ja, ich weiß, ich sollte meine eigene benutzerdefinierte Ausnahmeklasse machen. Aber das ändert nichts an dem, was hier passiert. Ich kann kein Try-Catch weiter oben im Stack finden. Ich habe einen Exception-Handler, wo, wenn eine Ausnahme in der Anwendung ausgelöst wird, es Environment.Exit(1); protokolliert dann die Ausnahme in einer Textdatei. Ich habe den Exception-Handler vollständig entfernt und sehe immer noch das gleiche Verhalten.

Es liegt nicht an den regionalen Einstellungen...

Und wie auch immer, alles beiseite, dies immer noch nicht erklären, warum die Ausnahme wie beabsichtigt in XP ausgelöst wird (und die App abstürzt und protokolliert Ausnahme in Datei), während in Win7 - die Ausnahme ignoriert wird und die Ausführung fortgesetzt.

2voto

Robert Seder Punkte 1360

Erstens: Sie sollten wirklich Ihre eigenen Ausnahmen einführen. System.Exception ist die Top-Level-Ausnahme, von der alle Ausnahmen erben. Erstellen Sie zum Beispiel eine DataFormatException - und werfen Sie diese.

Weiter, es klingt wie Sie wahrscheinlich System.Exception jemand tiefer im Stapel, die diese Ausnahme verschluckt fangen. Auch hier wäre es ideal, wenn Sie nur System.Exception an der niedrigsten Stelle im Stack für diesen Thread abfangen und dies als Auffanglösung für die gesamte Anwendung verwenden. An anderen Stellen in Ihrem Code sollten Sie die Ausnahmen abfangen, die Sie erwarten. Beispielsweise sollte der Aufrufer Ihrer Methode nur versuchen, DataFormatException und ArgumentException abzufangen (die Sie auslösen sollten, wenn "doublevar" null oder leer ist). Zum Beispiel:

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

Ich hoffe, das hilft...

1voto

Steve Sheldon Punkte 6131

Ich nehme an, Sie verwenden tryparse hier und rethrowing die Ausnahme nur um zu zeigen, dass try parse nicht wie erwartet funktioniert... Warum nicht versuchen, ein Debug.Print innerhalb der if-Anweisung hinzuzufügen, um zu sehen, was Sie erhalten.

Stellen Sie außerdem sicher, dass dieser Code nicht von einer anderen Funktion aufgerufen wird, die diesen Code mit einem try/catch-Block umschließt, der die Ausnahme verschluckt

1voto

Dean Harding Punkte 69243

Wenn Sie im Debug-Modus durchgehen, können Sie sehen, dass die Ausnahme ausgelöst wird, richtig? Was passiert danach? Das heißt, nachdem die throw new Exception() Zeile, wo landen Sie, wenn Sie F10 drücken? Das ist der Punkt, an dem die Ausnahme verschluckt wird.

Wenn Sie irgendwo im Framework-Code landen, bedeutet das, dass Sie manuell ein Try...catch in den Code einfügen müssen, der die Datei verarbeitet:

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

0voto

repka Punkte 2837

Wahrscheinlich unterscheiden sich Ihre Computer in ihren regionalen Einstellungen. Zum Beispiel unterscheiden sich die Tausender-/Dezimaltrennzeichen zwischen den Ländern, z. B. "1.000,00" gegenüber "1.000,00", DateTime unterschiedliche Formate, usw. Versuchen Sie, Parse/TryParse/ToString-Überladungen zu verwenden, die Folgendes angeben CultureInfo explizit und vermeiden Sie die Standardeinstellungen des Computers, z. B. durch die Verwendung von CultureInfo.InvariantCulture .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X