Laden...

An welcher Stelle Exception bei mehreren Forms fangen?

Erstellt von Nelson vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.552 Views
N
Nelson Themenstarter:in
26 Beiträge seit 2010
vor 13 Jahren
An welcher Stelle Exception bei mehreren Forms fangen?

Hallo zusammen,

ich habe das Problem, dass eine eigene Exception, die ich auslöse, nicht so verarbeitet wird wie ich es erwarte.

Wenn ich mit dem Debugger arbeite funktioniert aber alles genau so wie es nach meinem Verständnis sein sollte !?

Meine Aufrufhierarchie sieht so aus:

static void Main
-> Aufruf Form1 (enthält DataGridView)
--> Doppelklick auf Form1.DataGridView
---> Aufruf Form2
----> Im Konstruktor für Form2: Aufruf einer Routine, die in einer .dll ausgelagert ist
-----> dort wird meine eigene Exception ausgelöst.

Die Forms rufe ich jeweils mit ShowDialog() auf.
Das Exception-Handling habe ich in static void Main untergebracht. Da ich eine durchgehende Aufrufhierarchie habe hätte ich jetzt erwartet, dass die Exception aus dem .dll ganz oben abgefangen wird. Dem ist aber nicht so.

Ich kann die gleiche Exception aus demselben .dll auch bereits im Konstruktor von Form1 auslösen und dann greift das ExceptionHandling wie gewünscht.

Und wie gesagt: Wenn ich das identische Programm debugge wird der Fehler auch beim Laden von Form2 korrekt in der Main-Routine verarbeitet.

Woran kann das liegen ? oder hab ich nen Denkfehler ?

Ich arbeite mit Visual C# Express 2008.

6.911 Beiträge seit 2009
vor 13 Jahren

Hallo,

ich glaub du vergisst dass in der Main-Methode "nur" die Nachrichteschleife von WinForsm gestartet wird. Dort hilft dir ein try-catch dann nix -> siehe ApplicationUnhandeldException.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo Nelson,

... außerdem bringt jedes ShowDialog seine eigne Nachrichtenschleife mit.

Exceptions solltest du bei Windows Forms in allen EventHandlern fangen. In Windows Forms gibt es sowas wie eine zentrale Stelle nicht so richtig.

herbivore

N
Nelson Themenstarter:in
26 Beiträge seit 2010
vor 13 Jahren

... außerdem bringt jedes ShowDialog seine eigne Nachrichtenschleife mit.

Ok, das war mir nicht klar. Wann endet diese Nachrichtenschleife denn genau ? Denn wenn ich in Form1 das Form2 so aufrufe:

try {           
       Form2.ShowDialog();
}
catch (MyException e)
{
    throw (e);
}

... und in Form2 (wie anfangs beschrieben) die Exception ausgelöst wird, dann lande ich in dem Catch-Block. Das heißt doch, daß auch nach Ende von ShowDialog() diese Nachrichtenschleife noch verfügbar ist, oder ? Zumindest solange der Dispose nicht erfolgt ist ?

Wenn ich jetzt auch in der Main-Routine die Form1 analog aufrufe und in Form1 eine separate Exception auslöse (also unabhängig von Form2), dann greift auch der Catch-Block in Main (widerspricht das jetzt dem was Du geschrieben hast @gfoidl ?)

ABER:
Die Exception aus Form2, die ich abfangen und weiterleiten möchte, die wird in der Main-Routine nicht gefangen. Warum macht das einen Unterschied ?

Und dann bleibt noch das "Phänomen" Debugger. Denn auch die Variante mit den Try-Catch-Blöcken funktioniert dort so wie ich es erwarte. (was nix heißen muss ...) Das heißt auch die weitergeleitete Exception wird von dem Catch-Block in Main abgefangen.

Also ich fürchte ich habs noch nicht gecheckt. Kann nochmal jemand mit nem Zaunpfahl winken, ohne daß es mich gleich erschlägt ? 😁

1.820 Beiträge seit 2005
vor 13 Jahren

Hallo!

Ich kenne zwar den Context deiner Anwendung nicht, aber evtl. kannst du es auch so umsetzen:
Wird in Form2 (aufgerufen durch Doppelklick in DGV) ein Fehler ausgelöst, könnte dieser auch dort abgefangen werden und der Dialog mit Cancel beendet werden. Dies kannst du dann im Doppelklick-EventHandler prüfen, und ggf. eine Meldung ausgeben.
Vorteil: Wird die Form2 später einmal noch woanders benötigt, muss die Fehlerbehandlung nicht doppelt implementiert werden, außerdem bricht nicht die komplette Anwendung ab.

Nobody is perfect. I'm sad, i'm not nobody 🙁

N
Nelson Themenstarter:in
26 Beiträge seit 2010
vor 13 Jahren

Hallo tom-essen,

ja, ich hab für mich schon ne Lösung gefunden, die in die Richtung geht. Mir gehts aber darum das prinzipiell ganz zu verstehen weil das ja was ist was einen auf Schritt und Tritt verfolgt.

Und im Moment bliebe da ein ungutes Gefühl weil ich noch Widersprüche sehe, die ich net auflösen kann ...

R
103 Beiträge seit 2009
vor 13 Jahren

Das Phänomen mit den nicht gefangenen Exceptions kommt mir irgendwie bekannt vor.

Ich habe in meiner Applikation folgende Exceptionhandler vor das Application.Run
gesetzt:

//exception handling
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(getUncaughtGUIThreadException);

//gui thread exception handling
          Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(getOtherUncaughtException);

Das funktioniert soweit ganz gut, ich nutze das aber nicht generell fürs Exception Handling (Ist meistens wie schon gesagt besser in der Form selbst) sondern nur für die wirklich unerwarteten Fälle. Bei meiner Implementierung kommt dann nur noch ein Fenster "A critical error has occured, please restart app and ask you admin" oder sowas und das ganze wird noch in einer Textdatei fürs nachverfolgen festgehalten.

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo Nelson,

Das heißt doch, daß auch nach Ende von ShowDialog() diese Nachrichtenschleife noch verfügbar ist, oder ?

nein, das heißt, dass ShowDialog erst endet, wenn das mit ShowDialog angezeigte Form geschlossen wurde. ShowDialog kehrt im Gegensatz zu Show eben nicht sofort zurück nachdem das Form angezeigt wurde, sondern erst nachdem es wieder geschlossen wurde.

Allerdings ist ShowDialog sowieso nicht mehr zeitgemäß. Siehe Warten auf Schließen einer anderen Form (und warum man Dialoge nicht modal machen sollte).

herbivore