Hijacking UnhandledException, um die Ausführung von Anwendungen mit mehreren Threads aufrechtzuerhalten

8

Situation
Nun, wie Sie unten sehen können, habe ich eine Haupt-App, die einen Thread erstellt, der eine Menge Hintergrundarbeiter erzeugt. Wenn der RunWorkerCompleted auf einen BG-Mitarbeiter ausgelöst wird, fällt manchmal eine Unhandled-Exception ab (aus einem Grund, den ich genau bestimmt habe, aber das ist nicht der Fall).

Die Protokolle zeigen also deutlich, dass mein UnhandledException-Handler eingegeben wurde und meldet die Ausnahme. Ich weiß, dass ich die OnUnhandledException absichtlich missbrauche, indem ich das Beenden der App unter Verwendung einer Console.Read () unterbreche. Ich habe es absichtlich gemacht , weil ich vor dem Beenden der App eine menschliche Intervention / Überprüfung durchführen möchte.

%Vor%

Was jedoch nur eine "Pause" vor dem manuellen Beenden sein sollte, hielt die App am Leben, dh der Thread erzeugt immer noch Arbeiter und führt als ob nichts passiert . Sogar Weider: Die UnhandledException wird immer wieder von Zeit zu Zeit gelöscht, wenn es erneut passiert. Und es wird jedes Mal protokolliert und verhält sich so, als wäre es ein einfacher Versuch. (Dies war das Standardverhalten vor .Net 3.0)

Frage
Warum passiert also alles, als ob die UnhandledException nicht ausgelöst wurde und der Thread und BG weiter laufen, als ob nichts passiert wäre? Meine Vermutung: Solange der OnUnhandledException-Handler noch nicht fertig ist und die App noch am Leben ist, leben alle noch laufenden Threads in einer freien Welt und machen ihre Arbeit.

Das gibt mir eine schlechte Versuchung, das Design zu behalten, als Versuch, die unhandled Exception zu fangen.
Ich weiß, das ist keine saubere Idee, wie man nie weiß, ob die Ausnahme ist ernst oder etwas, das übersprungen werden könnte. Jedoch würde ich wirklich bevorzugen, dass mein Programm den ganzen Tag weiter läuft und den Protokollbericht / die Mailwarnungen sieht und für mich selbst entscheidet, ob es neu gestartet werden muss oder nicht. Da es sich um eine Server-Anwendung handelt, die rund um die Uhr laufen muss, wollte ich unzeitgemäße und sich wiederholende Unterbrechungen aufgrund geringfügiger, noch nicht behandelter Ausnahmen vermeiden. Der größte Vorteil besteht darin, dass das Serverprogramm weiterläuft, während wir unbehandelte Ausnahmen einzeln aufspüren und Patches bereitstellen, um sie bei ihrem Auftreten zu behandeln.

Vielen Dank für Ihre Geduld. Bitte geben Sie uns Feedback.

PS: Nein, ich habe keinen Pot geraucht.

    
Mehdi LAMRANI 19.01.2012, 10:12
quelle

3 Antworten

3
  

Meine Schätzung lautet so lange, wie der OnUnhandledException-Handler nicht funktioniert   fertig, und die App ist noch am Leben, alle laufenden Threads, die still sind   Lebe weiterhin in einer freien Welt und mache ihre Arbeit.

Richtig. Aber Ihre anderen Threads machen jetzt ihre Arbeit in einem möglicherweise instabilen Prozess. Es gibt gute Gründe für das Beenden der App, wenn eine unbehandelte Ausnahme auftritt.

  

Ich würde wirklich bevorzugen, dass mein Programm weiterläuft

Neben den (potentiellen) Stabilitätsproblemen würden Sie den angehaltenen Zustand von allem, was an der unbehandelten Behandlung beteiligt ist, ansammeln. Meine Vermutung ist, dass Sie jedes Mal einen Thread verlieren würden, wenn es passiert. Und Sie können nicht zu viele von ihnen verschonen.

Es wäre also ein sehr schlechtes Design und würde den Absturz nur verzögern.

    
Henk Holterman 19.01.2012, 10:43
quelle
2

Zunächst müssen Sie den UnhadledThreadException-Handler abonnieren. Dort können Sie die Ausnahme nicht "entführen", aber Sie haben Zugriff darauf und auch auf den Thread, zu dem sie gehört. Was du jetzt tun kannst, ist den Wurffaden in die Suspendierung zu legen. Der Thread wird noch am Leben sein !! Dies ist jedoch ein schlechter, schmutziger Hack! Tu das nicht!

Sehen Sie sich diesen Artikel für einige Details an .

Ich empfehle, das Threading-Modell auf TPL umzustellen (Design bleibt bestehen). Dort haben Sie Zugriff auf diese hässlichen Cross-Thread-Exceptions und können sie elegant handhaben / unterdrücken.

    
Jaster 19.01.2012 10:34
quelle
1

Wenn Sie zulassen möchten, dass ein BackgroundWorker-Thread fehlschlägt, ohne den gesamten Prozess zu beenden, können Sie dies auf einfachere Weise tun.

Zuerst fangen Sie die RunWorkerCompleted Ereignis. Dieses Ereignis wird ausgelöst, wenn der BackgroundWorker-Thread entweder normal oder über eine unbehandelte Ausnahme beendet wird. Suchen Sie dann in Ihrem Event-Handler nach der unbehandelten Ausnahme:

%Vor%

Auf diese Weise können Sie den BackgroundWorker-Thread sterben lassen und jede Ausnahme protokollieren, ohne den gesamten Prozess zu beenden.

    
RoadWarrior 19.01.2012 12:55
quelle

Tags und Links