| 

.NET C# Java Javascript Exception

3
Hallo,

zur Info: Unter Debug > Exceptions in der Spalte Thrown ist nichts angehackt.

Das Problem stellt sich wie folgt dar:

Beim Programmstart (siehe Code unten) wird die Methode exceptionTest() ausgeführt. Starte ich das Programm ohne Debugging, werden, wie gewünscht, zwei MessageBoxen mit den Exception-Messages angezeigt. Starte ich das Programm mit Debugging, wird nur die erste Exception bearbeitet, bei der zweiten Exception wird das Programm an der throw-Anweisung angehalten. Wie lässt sich das erklären?

private void exceptionTest() {
try
{
throw new Exception("Ups..."); //Exception 1
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

Task t = Task.Factory.StartNew(met);
t.ContinueWith(bescheid);
}

private void met() {
Debug.WriteLine("Enter Task");
Thread.Sleep(2000);
throw new Exception("Noch 'n Ups..."); //Exception 2
}

private void bescheid(Task t) {
try
{
t.Wait();
}
catch (AggregateException ex)
{
MessageBox.Show(ex.InnerExceptions[0].Message);
}
}


Mache ich weiter mit F5, wird auch die zweite Exception bearbeitet, jedoch kann ich mir nicht erklären, warum der Debugger an der zweiten throw-Anweisung anhält.
02.03.2014
Siggi 229 7
Ist es eine FirstChance - Exception, die der Debugger meldet?
ffordermaier 02.03.2014
@ffordermaier: Ja, das meldet der Debugger im Output-Fenster.
Siggi 02.03.2014
2 Antworten
1
Ok, ich habe Deinen Code kurz angetestet. Die Ausnahme in der Methode met() wurde von Dir nicht behandelt und deshalb bleibt der Debugger dort stehen. Dass diese später von der TPL in der AggregateException zusammengefasst wird, ist eine andere Sache.
Wenn Du möchtest, dass der Debugger bei der von Dir behandelten Ausnahme nicht anhält, musst Du in den Exceptions-Einstellungen das Häkchen bei user-unhandled (das rechte der beiden Häkchen) auch noch entfernen.
02.03.2014
ffordermaier 8,4k 3 9
Dann weiß ich Bescheid, wenn ich diese Verhalten mal eben abstellen möchte.

Danke.
Siggi 02.03.2014
1
Das zweite ist eine AppDomain.UnhandledException, die aus einer Application.ThreadException entsteht. Du kannst dich zu einem der beiden Events verbinden, um einen Handler zu implementieren. Wobei natürlich beides unschön ist, ein Handler im Thread sollte her, sonst kommt es auch u. U. zu Memory Leaks.

@edit - Nachtrag:

Der Grund warum die zweite Exception ohne Debug nicht feuert ist vermutlich Application.UnhandledExceptionMode - wenn man diesen auf UnhandledExceptionMode.ThrowException setzt, stürzt auch das Programm ab.

Zur Frage der Implementierung:

Es geht derzeit zur Laufzeit eine Exception verloren, die möglicherweise Memory Leaks verursacht. Ignorieren von Exceptions ist ohnehin das unschönste was man tun kann. Definiertes Errorhandling immer an der Stelle, an der der Fehler auftritt ist zu implementieren.

Die AggregateException ist nützlich um im Nachhinein abzufragen, aber so wie das Beispiel implementiert ist, hast du dennoch einen Thread, der mit einem unbehandelten Fehler terminiert (was momentan im Nicht-Debug-Mode ignoriert wird). Das sollte verhindert werden.
02.03.2014
Maria Simlinger 1,1k 1 9
Wie heißt dann die erste Exception?

Sollte ich auf jeden Fall einen Handler implementieren? Ohne den Debugger kann ich ja die Exceptions abfangen und darauf entsprechend Reagieren.
Siggi 02.03.2014
@Maria: Zur Laufzeit geht keine Exception verloren. Die Exception, die in der Methode met() geworfen wird, wird von der TPL gefangen und eingesammelt, später in der Methode bescheid(Task t) als eine InnerException der AggregateException mitgeteilt. Es gibt durchaus Fälle, an denen eine Exception an der Stelle, an der sie auftritt, nicht behandelt werden kann. Dann wandert sie im CallStack einfach weiter, bis irgendwo ein Handler erwischt wird. Siehe auch z.b. die Tatsache, dass eine Task mit einem CancellationToken und Aufruf der Methode ThrowIfCancellationRequested() abgebrochen werden kann.
ffordermaier 02.03.2014
@ffordermaier: Ja, es funktioniert wie ein "On Error Resume Next" bis die AggregateException ausgewertet wird. Ich bin mir nicht sicher, ob das dem Fragesteller bewusst war. Jedenfalls sehe ich keine Lösung darin User Unhandled Exceptions in der Debug Umgebung abzudrehen, solange ich mir nicht *wirklich* sicher bin, dass ich das will.
Maria Simlinger 02.03.2014
1
@Maria: Da bin ich voll bei Dir.
Ich habe die Frage derart interpretiert, als dass eben der Debugger nicht mehr anspringen soll. Das wurde erreicht. Zur Sinnhaftigkeit habe ich mich nicht geäußert.
Da @Siggi keinen UseCase skizziert hat, habe ich angenommen, dass er wissen will, wie die Debugger-Einstellungen zu treffen sind.
Sobald er konkrete Anforderungen formuliert, bin ich mir relativ sicher, dass die Lösung anders aussieht. Aber bis dahin rate ich in einfach mal ins Blaue hinein :-) ... und hoffe damit, schnell helfen zu können...
Exception-Diskussion könnten wir ja in der Lounge...
ffordermaier 02.03.2014

Stelle deine Threads-Frage jetzt!