myCSharp.de - DIE C# und .NET Community (https://www.mycsharp.de/wbb2/index.php)
- Entwicklung (https://www.mycsharp.de/wbb2/board.php?boardid=3)
-- GUI: WPF und XAML (https://www.mycsharp.de/wbb2/board.php?boardid=85)
--- Vorgehensweise Umgang mit Fehlern MVVM (https://www.mycsharp.de/wbb2/thread.php?threadid=122611)


Geschrieben von CodeF am 05.02.2020 um 07:23:
  Vorgehensweise Umgang mit Fehlern MVVM
Hi, wie wäre für folgendes der richtige Weg?

In einer MVVM-Anwendung würde aus der Businesslogik heraus eine Methode in einer Klasse für einen Datenimport per CSV aufgerufen. Diese ist für das Laden und das Aufbereiten der Daten zuständig. Nun können da ja verschiedene Fehler passieren:

- Datei nicht zugreifbar
- Daten nicht auswertbar
- Version der Datendatei veraltet

Bei manchen dieser Fehler würde eine Exception auslösen und wird daher mit einem Try/Catch abgefangen, andere würden per Code bei der Auswertung entstehen.

Wie wird nun die BL und der Anwender über diese Fehler informiert? In der CVS-Laden-Klasse sollen keine MsgBoxen und sowas enthalten sein.

Möglichkeiten wären meiner Meinung nach:
- Rückgabewert über Enum
- Exceptions und eingene Exceptions
- ?

Wie sieht das aus wenn ein Backgroundworker verwendet wird was durchaus sinnvoll ist?

Gruß


Geschrieben von Abt am 05.02.2020 um 09:02:
 
Prinzipiell Exceptions; das sieht das gesamte .NET Konzept so vor.
Gibt dazu in den .NET Guidelines auch eine eigene Sektion, wie, weshalb und warum.


Geschrieben von inflames2k am 05.02.2020 um 11:21:
 
So strikt würde ich es jetzt nicht unbedingt machen. Bei API's und größeren Projekten handhaben wir es meist so, dass jede Methode der BusinessLogik einen entsprechenden Rückgabetyp hat.

Für das lesen von Daten aus der Datenbank beispielsweise etwas wie:

C#-Code:
public class GetUserDataResult
{
      ///
      // Gets or sets if getting user data succeeded
      ///
      public bool Success { get; set; }

      ///
      // Gets or sets the error text if the data call failed
      ///
      public string Error { get; set; }

      ///
      // Gets or sets the user data
      ///
      public UserData UserData { get; set }
}

Success und Error kommen hier natürlich aus einer gemeinsamen Basisklasse für Aufrufergebnisse.

Klar würde es auch mit Exceptions bis Stelle x ausreichen. Wir reden aber im von CodeF genannten Fall von erwarteten Fehlern die auch entsprechend behandelt werden sollten.


Geschrieben von Palladin007 am 05.02.2020 um 11:48:
 
Und warum könnte man diesen erwarteten Fehlern nicht einfach einen eigenen Exception-Typ (oder Ableitungen davon pro Fehler) geben?

So muss man diese Klasse überall hin durch reichen und wenn man das Mal nicht tut (vergessen, Faulheit, etc.), gehen diese Fehlerinformationen verloren.

Mit einer Exception ist das egal.
Man muss (soll) sie nirgendwo beachten, wo man sie nicht behandeln kann. Sobald man sie behandeln kann, kann man auch ein try-catch schreiben und diesen eigenen Exception-Typ abfangen.
Das musst Du am Ende sowieso, denn es kann ja immer noch eine Exception auftreten.


Geschrieben von Abt am 05.02.2020 um 12:02:
 
Bei APIs macht man das aufgrund vom Technologiebruch, zB .NET auf JSON.
Bei APIs ohne Technologiebruch bzw. ohne Auswirkung des Bruchs wie zB WCF oder gRPC, macht man das i.d.R. nicht.

Wenn also kein Workaround notwendig ist, dann ist so ein vorgehen unnütz bzw. Kontraproduktiv.

Eine solche Klasse in der Business Logik stufe ich persönlich als großen Designfehler ein.
Er bricht klar die Empfehlungen und Prinzipien von Software Architektur in dem Bereich.


Geschrieben von inflames2k am 05.02.2020 um 13:29:
 
Das ändert m.E. nichts am oben genannten Szenario wo wir von erwarteten Fehlern reden. Die sollten auf keinen Fall als Exception nach außen geworfen werden sondern eigentlich zuvor schon abgefangen / behandelt werden.


Geschrieben von Palladin007 am 05.02.2020 um 14:12:
 
Eine Exception kann sowohl erwartet als auch unerwartet sein.

Die unerwarteten Exceptions sollten nicht gefangen oder zumindest weiter geworfen werden.

Die erwarteten Exceptions sollte man erst dann fangen, wenn man sie auch wirklich behandeln kann. Sie vorher abzufangen und mit weniger Infos in ein eigenes Objekt zu packen, macht meiner Meinung nach überhaupt keinen Sinn.


Geschrieben von CodeF am 17.02.2020 um 21:15:
 
Ich hab mir die NET Guidelines und auch "Best Practices für Ausnahmen" angeguckt.

So wie ich es verstanden habe, ist da das Mittel der Wahl Exception. Aber nur wenn nicht schon davon augegangen wird, das ein Fehler auftritt. Darum gibt es dann die z.B. TryParse-Methoden. Die sollen dann vorrangig verwendet werden.
=> Fehlervermeidung zuerst, und dann erst Exceptions!


Nur wie sieht es aus, wenn Exceptions innerhalb eines Backgroundworkers erzeugt werden?

Mann kann in der WorkerComplete-Methode das e.Error abfragen und schauen, ob allgemeine oder eine eigene Exception ausgelöst wurde. Hier müsste dann aber die Exception neu geworfen werden um den Fehler an die aufrufende Klasse weiterzuleiten. Leider funktioniert dies bei mir nicht. Führt dann zu einen Fehler in der mscor.lib.

Wie denkt Ihr darüber?


Geschrieben von Abt am 17.02.2020 um 22:15:
 
Ich denke so darüber, dass man den Backgroundworker prinzipiell gar nicht mehr braucht, da es mittlerweile eben Tasks gibt, die quasi jeden Verwendungszweck des Backgroundworkers übernommen haben.

Rein prinzipiell kann man aber auch mit dem Backgroundworker so programmieren, das das Handhaben von Exceptions kein Problem ist.
Das ist dann "einfach" das Thema von Software Architektur und der Anwendung von Code Pattern.


Geschrieben von CodeF am 19.02.2020 um 07:31:
 
Guten Morgen,

irgendwie komme ich da nicht zurecht.

Wenn ich davon ausgehe dass eine länger andauernde Sache mittels Backgroundworker ausgeführt wird um die GUI nicht zu blockieren ist der Ablauf doch so:

1. Aus den GUI-Thread wird eine Methode aufgerufen z.B. LoadData

2. In dieser Methode LoadData wird ein Backgroundworker zur Arbeit herangezogen und gestartet

3. Das Programm kehrt in den GUI-Thread zurück da ja jetzt der BW die Arbeit macht

4. Im Backgroundworker wird eine Exception ausgelöst

5. In der Mehtode ...WorkerCompleted ist die Exception mittels Abfrage von e.Error abfragbar

Wie und auf welche weise soll nun der GUI-Thread über diese Exception benachrichtigt werden?
Auch wenn in der ...WorkerCompleted -Methode eine neue Exception geworfen wird, wer soll diese Abfangen? Der Aufruf aus 1. ist ja schon lange vorbei.


Geschrieben von inflames2k am 19.02.2020 um 08:28:
 
Im einfachsten Falle gibt es dafür Events.

Der BackgroundWorker allerdings ist ein schlechtes Beispiel. - Denn im WorkerCompleted musst du keine weitere Exception werfen. Du kannst den Fehler direkt auswerten und in irgend einer Art und Weise ausgeben.


Geschrieben von CodeF am 20.02.2020 um 06:43:
 
Hi, evt. hab ich das dann falsch aufgebaut oder verstanden.

Der Backgroundworker befindet sich nun mal in meiner Klasse für das Laden.

In dieser möchte ich aber nichts mit Fehlerausgabe oder sowas machen (MVVM).

Wie isz hier nun die richtige vorgenhensweise. Events? Und dann? Doch wieder über Argumente die Fehler melden?


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 05.06.2020 17:03