Laden...

Exceptions in einem BackgroundService

Erstellt von TotalerASPNETN00B vor 2 Jahren Letzter Beitrag vor 2 Jahren 502 Views
T
TotalerASPNETN00B Themenstarter:in
20 Beiträge seit 2021
vor 2 Jahren
Exceptions in einem BackgroundService

Hallo Community,

Ich hoffe die Kategorie ist richtig gewählt 😉

Ich habe eine Frage zu dem BackgroundService ich habe merhfach gelesen das man keine Exceptions werfen kann (in .Net 5), stimmt das ? Falls ja, gilt dies nur für die Methoden wie ExecuteAsync usw. oder für alle Methoden (oder auch zusätzliche selbstgeschriebene Hilfsmethoden) innhalb der Klasse ?

Und gibt es "gute" alternativen zu Exceptions in BackgroundService "Kontext" ?

Hat da jemand praktische Erfahrungen mit Exceptions im BackgroundService Bereich ?

P
441 Beiträge seit 2014
vor 2 Jahren

Was möchtest du denn mit den Exceptions erreichen?

Der BackgroundService ist in sich geschlossen, eine Exception würde dazu führen, dass er abstürzt. In deiner App ist er nur insofern eingebettet, dass er an den Lifecycle der Applikation gebunden ist.

Wer sollte die Exception fangen?

T
TotalerASPNETN00B Themenstarter:in
20 Beiträge seit 2021
vor 2 Jahren

Was möchtest du denn mit den Exceptions erreichen?

Ich möchte u.a. dem User mitteilen wenn etwas nicht so lief wie gewünscht

16.806 Beiträge seit 2008
vor 2 Jahren

merhfach gelesen das man keine Exceptions werfen kann (in .Net 5), stimmt das ?

Ich glaube nicht, dass Du das irgendwo gelesen hast.

Ich möchte u.a. dem User mitteilen wenn etwas nicht so lief wie gewünscht

Dann musst Du das über die Schnittstelle (was die auch immer ist, hast nirgends erwähnt und wir können nicht hellsehen) mitteilen.
Dafür gibts bereits Standards, zB REST.

T
TotalerASPNETN00B Themenstarter:in
20 Beiträge seit 2021
vor 2 Jahren

Ich meine Exceptions in BackgroundService. War vielleicht ungünstig formuliert.
Aber funktionieren im BackgroundService try/catch/finally Blöcke ?

16.806 Beiträge seit 2008
vor 2 Jahren

Zeig mal die Quelle, die Du "mehrfach" gelesen hast.
Exception Handling sind in allen .NET Anwendungen identisch. Auch in Background Services.
Nur gewisse Exceptions kann man in .NET nicht fangen: sobald der Prozess selbst defekt ist, zB. MemoryExceptions.

Mit Background Service hat das null komma null zutun.
Also entweder hast Du sehr dubiose Quellen oder Du liest / verstehst was völlig falsches.
Du scheinst da etwas ganz grundlegendes falsch zu verstehen...

T
TotalerASPNETN00B Themenstarter:in
20 Beiträge seit 2021
vor 2 Jahren

Also da hab ich das gelesen aber ich dachte es bezieht sich auf alle Probleme BackgroundService Gotcha: Silent Failures

16.806 Beiträge seit 2008
vor 2 Jahren

Du hast geschrieben:

ich habe merhfach gelesen das man keine Exceptions werfen kann (in .Net 5), stimmt das ? Falls ja, gilt dies nur für die Methoden wie ExecuteAsync usw. oder für alle Methoden (oder auch zusätzliche selbstgeschriebene Hilfsmethoden) innhalb der Klasse ?

In dem Beitrag steht:

exceptions are silently ignored.

Du hast es also völlig falsch verstanden.
Zwischen "man kann keine werfen" und "alle werden ignoriert" ist ein riiiiiiiiesen Unterschied.

Er erklärt ja auch in seinem Beitrag wieso das so gewollt ist - und was man machen muss.
Die Lösung hast Du also in seinem Beitrag.

T
TotalerASPNETN00B Themenstarter:in
20 Beiträge seit 2021
vor 2 Jahren

Er erklärt ja auch in seinem Beitrag wieso das so gewollt ist - und was man machen muss.
Die Lösung hast Du also in seinem Beitrag.

Aber ich bin verunsichert, ob das so richtig ist

16.806 Beiträge seit 2008
vor 2 Jahren

Wieso googelst Du dann nicht einfach? 🙂

zB einfach die offizielle Doku lesen?
Ausnahmefehler der Klasse „BackgroundService“

Oder GitHub - Exceptions in BackgroundService ExecuteAsync are (sometimes) hidden - erster Google Treffer.
Der gfoidl dort ist übrigens unser Benutzer gfoidl

Aber Deine Aussage, dass man keine .NET Exceptions mehr werfen kannst: die hast Dir einfach aus den Haaren gezogen.
Das steht nirgends - und ist auch nicht so.

6.911 Beiträge seit 2009
vor 2 Jahren

Hallo TotalerASPNETN00B,

Ich möchte u.a. dem User mitteilen wenn etwas nicht so lief wie gewünscht

Ein BackgroundService läuft wie dessen Name sagt im "Hintergrund". Du möchtest jedoch eine Mitteilung für den Benutzer, das spielt sich im "Vordergrund" ab. So direkt geht das nicht und das ist auch was Abt mit

Dann musst Du das über die Schnittstelle (was die auch immer ist, hast nirgends erwähnt und wir können nicht hellsehen) mitteilen.
Dafür gibts bereits Standards, zB REST.

meint.

Stell dir aber die Frag ob es sinnvoll ist dem Benutzer so etwas mitzuteilen. Das hängt davon ab was der BackgroundService machen soll.
Es kann auch vernüftiger sein, dass der BS den Fehler loggt und ein Admin, etc. so (via Logging bzw. Alerts) informiert wird und das Problem beheben kann.

Aufgrund deiner Aussage nehme ich an, dass der BS sein Arbeitsaufgaben vom Frontend / User bekommt und diese dann im Hintergrund abarbeiten soll, also eine Art "Queue-Processor". Hier sollte aber bereits im Frontend die Eingaben validiert werden, so dass im BS nur echte Fehler auftreten können (wie z.B. Fehler beim Zugriff auf die Datenbank) und keine vom Benutzer verursachten. Daher ist es auch nicht recht sinnvoll den Benutzer über diese Art der Fehler zu informieren.

Aber beschreib einmal genau was du vorhast, denn so bewegen wir und im Bereich von Raten und Annhemen.

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!"

T
TotalerASPNETN00B Themenstarter:in
20 Beiträge seit 2021
vor 2 Jahren

Aufgrund deiner Aussage nehme ich an, dass der BS sein Arbeitsaufgaben vom Frontend / User bekommt und diese dann im Hintergrund abarbeiten soll, also eine Art "Queue-Processor". Hier sollte aber bereits im Frontend die Eingaben validiert werden, so dass im BS nur echte Fehler auftreten können (wie z.B. Fehler beim Zugriff auf die Datenbank) und keine vom Benutzer verursachten. Daher ist es auch nicht recht sinnvoll den Benutzer über diese Art der Fehler zu informieren.

Hallo, auch dir danke für dein Feedback,

Ja genau möchte, halt den User imformieren wenn etwas in der Datenbank schief ging (damit er den Vorgang wiederholt). Aber das mit dem logging ist eine sehr gute Idee

6.911 Beiträge seit 2009
vor 2 Jahren

Hallo TotalerASPNETN00B,

wenn etwas in der Datenbank schief ging (damit er den Vorgang wiederholt)

Brauchst du dazu einen BackgroundService od. kann das direkt im Controller, etc. zur DB geschickt werden? Das würde die Komplexität der Anwendung reduzieren -- und auch potentielle Probleme wie du hier siehst. Wenns direkt im Controller passiert, so ist das im Vordergrund und es kann direkt dem Benutzer einen Meldung angzeigt werden od. bei einem HTTP-API ein entprechender Statuscode + Meldung.

Einen BS würde ich nur verwenden wenn die Aufgabe komplexer ist und länger dauert. Kurz: wenn der Vordergrund etwas in eine Warteschlange stecken soll, damit dies vom Hintergrund-Dienst verarbeitet werden kann.
Z.B. der BS muss dann selbst via HTTP-API andere Infos holen, mehrere DB-Aufrufe durchführen und am Ende eine Email verschicken.

Bezüglich Fehler bzw. "wenn etwas schiefging" so solltest du auch unterscheiden zwischen möglichen Fehler-Arten. Es gibt welche da kann der Benutzer eh nichts machen. Z.B. wenn ein Bug im Code ist od. welche die direkt im Code per "Retry" behandelt werden können.
Dann gibt es andere in Bezug auf Datenbank wie "concurrency issues", also wenn zwei Benutzer den gleichen Datensatz überschreiben würden, und das kann sehr wohl mit einer Benutzerinteraktion behoben werden.

Leider gibt es kein Universalrezept wie es zu machen ist, das hängt vom jeweiligen Anwendungsfall ab.
Aber starte einfach, komplizierter kann es immer werden -- im Idealfall nur dann wenn es eine konkrete Anforderung dazu gibt, wie dass der DB-Zugriff im Controller so lange dauert, dass es für den Benutzer nciht mehr nett ist.

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!"

T
TotalerASPNETN00B Themenstarter:in
20 Beiträge seit 2021
vor 2 Jahren

wenn etwas in der Datenbank schief ging (damit er den Vorgang wiederholt)
Brauchst du dazu einen BackgroundService od. kann das direkt im Controller, etc. zur DB geschickt werden? Das würde die Komplexität der Anwendung reduzieren -- und auch potentielle Probleme wie du hier siehst. Wenns direkt im Controller passiert, so ist das im Vordergrund und es kann direkt dem Benutzer einen Meldung angzeigt werden od. bei einem HTTP-API ein entprechender Statuscode + Meldung.

Ja die Zeit ist das Problem ohne Background servicedauert es zu teil sehr lang 10 sekunden und mehr, daher sammle ich die "Sachen" die ich bekommen hab in einer Queue und verarbeite diese dann im nachhinein dann dauert eine http Antwort nur 0.15 sekunden zirka, was halt extrem cool ist.

Und es klappt halt ansich gut, wenn es eben nicht zu einem Fehler kommt z.b in der DB.

Wie kann man denn in einer BS mit Cuncurrency Issues umgehen ?

6.911 Beiträge seit 2009
vor 2 Jahren

Hallo TotalerASPNETN00B,

Wie kann man denn in einer BS mit Cuncurrency Issues umgehen ?

Damit wir eh vom Gleichen sprechen: mit "Cuncurrency Issues" ist Handling Concurrency Conflicts - EF Core gemeint (od. halt für andere DBs / ORMs).

In Bezug auf BS selbst, steht es im Link vom letzten Absatz. Wenn du solche Fehler aber dem Benutzer zeigen willst, so ist das nicht so trivial. Da brauchst du irgendeinen Benachrichtigungsmechanismus wie SignalR, HTML5 Notifications (angestoßen von SignalR beispielweise), Email, etc. (HTML5 Push-Nachrichten würde ich eher vermeiden, da lästig IMO).
Aber das kann ich nicht beurteilen, da ich das Umfeld deiner Anwendung und deren Benutzergruppe nicht kenne.

Bedenke dabei:* Was ist wenn der User nicht mehr auf der Seite ist?
Dann geht SignalR schon nicht mehr und brauchst einen anderen Weg. Z.B. Email als Benachrichtigung. So machen es auch große Online-Versandhändler mit den Status-Emails.

  • Wenn

in einer Queue und verarbeite

sind dann überhaupt solche DB-Concurrency Issues möglich? Durch die Queue werden die DB-Zugriff serialisiert und daher Werte einfach überschrieben, außer du führst manuell ein solche Prüfung durch.

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!"

T
TotalerASPNETN00B Themenstarter:in
20 Beiträge seit 2021
vor 2 Jahren

Ich prüfe anhand der Id ob es bereits einen gleichen Eintrag in der DB gibt ansonsten update ich und arbeite so die Queue nach und nach ab

6.911 Beiträge seit 2009
vor 2 Jahren

Hallo TotalerASPNETN00B,

mit ein paar Infos mehr würdest das Helfen wollen leichter machen...

Kann dir Prüfung auf gleiche Id bereits im Controller erfolgen od. dauert auch das schon zu lange?
Wenn das ginge, so wäre die Benutzer-Meldung recht trivial. Und erst nach dieser bestandenen Prüfung gehts in die Queue zum BS.

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!"

T
TotalerASPNETN00B Themenstarter:in
20 Beiträge seit 2021
vor 2 Jahren

Kann dir Prüfung auf gleiche Id bereits im Controller erfolgen od. dauert auch das schon zu lange?

Es kann unterumständen zu lange dauern. Aber ein theoretischer Fall macht mir Kopfzerbrechen, was passiert wenn ein Vorgang (wie z.b eine Verarbeitung) im BS noch nicht abgeschlossen ist und in der Zwischenzeit ein weiterer Vorgang gestartet wird ? Wie handhabt das der BS ?

P
441 Beiträge seit 2014
vor 2 Jahren

Ich würde dir empfehlen, dir einmal den Prozess aufzumalen und zu visualisieren.

Wenn dein Background Service keine parallele Verarbeitung kann, wird er immer nur ein Item aus der Queue entnehmen und verarbeiten. Ein neues Item wird dann in der Queue verbleiben, bis die Verarbeitung des vorherigen abgeschlossen ist.

Hast du denn schon einmal Beispiel Implementierungen gemacht und ein wenig herumgetestet?