[Sammlung] Sinnvolle Verwendungen für Try-Catch

  • Allgemein

Es gibt 34 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    [Sammlung] Sinnvolle Verwendungen für Try-Catch

    Da der Verwendungszweck von Try-Catch Blöcken vor allem für Anfänger nur schwer nachvollziehbar ist (und man im Netz haufenweise MessageBoxen im Catch Teil findet) habe ich mir gedacht, dass eine Sammlung von sinnvollen Verwendungen nicht schaden kann.
    Natürlich ist zu sagen, dass die Fehlerbehandlung sehr vom Programm selbst abhängt und hier nur schwer bis gar nicht beschrieben werden kann.

    Vorab möchte ich den Artikel von ErfinderDesRades hier verlinken, da er viele wichtige Informationen enthält.

    Edit:
    Da ich mich nicht in allen Themengebieten auskenne wäre es schön, wenn Codebeispiele dazugepostet werden.
    Einfache Schnipsel wie

    VB.NET-Quellcode

    1. Try
    2. Bipm = DirectCast(Image.FromFile("C:\Userds\Administrator\Desktop\Datei.png"), Bitmap)
    3. Catch ex As OutOfMemoryException
    4. 'Datei beschädigt oder zu groß
    5. End Try

    reichen dabei aus. Wichtig ist das Kommentar im Catch Teil, in dem steht, wann und warum die Exception fliegt.
    /Edit

    GDI+ und Bilder

    Erstellen von Bitmaps aus Dateien:
    Wenn die Datei fehlerhaft oder zu groß ist, dann wird eine OutOfMemoryException geworfen.
    Mir ist bisher keine andere Möglichkeit bekannt auf diese beiden Fälle anders zu reagieren.

    VB.NET-Quellcode

    1. Dim Bipm As Bitmap
    2. Try
    3. Bipm = DirectCast(Image.FromFile("C:\Userds\Administrator\Desktop\Datei.png"), Bitmap)
    4. Catch ex As OutOfMemoryException
    5. 'Datei beschädigt oder zu groß
    6. End Try
    7. DoSomething(Bipm)



    IO

    Erstellen und Öffnen von Dateien:
    Wo hier der Unterschied zwischen UnauthorizedAccessException und SecurityException bei fehlenden Rechten ist wird auch in MSDN nicht erklärt.

    VB.NET-Quellcode

    1. Try
    2. System.IO.File.WriteAllText("Pfad", "Inhalt")
    3. Catch ex As UnauthorizedAccessException
    4. 'Datei ist ReadOnly
    5. 'Pfad zeigt auf einen Ordner
    6. 'Erforderliche Rechte fehlen
    7. Catch ex As System.Security.SecurityException
    8. 'Erforderliche Rechte fehlen
    9. End Try



    WebRequests, etc.

    Verbindungsabbruch (während Datenübertragung):
    Noch kein Codebeispiel


    Datenbanken / Datasets

    Lesezugriff auf spezielle XML Dateien:
    Noch kein Codeschnipsel.

    DataSet.ReadXML:
    Noch kein Codebeispiel


    Sonstiges

    Ver- / Entschlüsselung:
    Siehe Post #35.

    WMI Abfragen:
    Noch kein Codebeispiel

    ReaderWriteLock für ein Timeout (ka was das ist)
    Noch kein Codebeispiel
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Niko Ortner“ ()

    'Bitmap.FromFile() gibt aus unerfindlichen Gründen ein Image zurück

    Bitmap erbt von Image, FromFile ist eine statische Funktion der Image-Klasse und statische Funktionen können nicht überschrieben werden.
    Daher ist es meiner Meinung nach sinnvoller, es so zu schreiben:

    VB.NET-Quellcode

    1. Bipm = DirectCast(Image.FromFile(...), Bitmap)

    So weiß man sofort, dass die FromFile-Methode der Image-Klasse aufgerufen wird, auch wenn's letztendlich dasselbe ist.

    Niko Ortner schrieb:

    Ein Beispiel mit Bitmaps:
    Wenn die Datei fehlerhaft oder zu groß ist, dann wird eine OutOfMemoryException geworfen.
    Mir ist bisher keine andere Möglichkeit bekannt auf diese beiden Fälle anders zu reagieren.

    Pauschal würdich da auch nicht zustimmen. Also eine Bildbearbeitungs-Software soll natürlich nicht crashen, wenn eine defekte Bild-Datei auftritt.
    Aber wenn das Bild zu den Resourcen der App gehört (im weitesten Sinne), dann kann auch ein behebbarer Programmierfehler vorliegen, und statt TryCatchens sollte der Progger lieber valide BildDateien mitliefern.
    Kann man glaub so verallgemeinern: Eine Dokumenten-Bearbeitung soll wohl üblicherweise nicht crashen, wenn versucht wird, ein defektes Dokument zu öffnen.
    Also bei allem, was Dateien öffnet, die der User mittels OpenFileDialog oder sowas bestimmt, wird gegen Ende des Entwicklungsprozesses, wenn auch solche Fälle getestet werden, ein TryCatch wahrscheinlich sinnvoll.
    @ErfinderDesRades:
    Da hast Du natürlich recht. Wenn es eine Ressource des Programmes ist sollte ein Try-Catch nie nötig sein.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Sinnvolle Verwendung für Try-Catch wärend des Debuggens (und nur dann): Wenn GDI+ mal wieder nur ein rotes Kreuz auf weißem Grund zeichnet und jegliche Fehlermeldung schluckt. Dann hilft ein kleines Try-Catch mit MsgBox(ex.ToString) im Paint-Event, um die fehlerhafte Zeile zu identifizieren.

    Skybird schrieb:

    Das sind ja Ubisoftmethoden hier !

    Also mir ist das mit dem roten Kreuz nur bei fertigen Anwendungen (nicht im Debugging) passiert. Und auch nur dann, wenn vorher schon mal eine Exception geflogen ist.
    Aber im Debugging ist mir das noch nie passiert.

    Mal sehen, was andere dazu zu sagen haben.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

    ErfinderDesRades schrieb:

    Aber wenn das Bild zu den Resourcen der App gehört (im weitesten Sinne), dann kann auch ein behebbarer Programmierfehler vorliegen, und statt TryCatchens sollte der Progger lieber valide BildDateien mitliefern.

    Bilder werden durch eine Komponente des Betriebssystems geladen, gezeigt etc. Nehmen wir an der Entwickler hat einen Rechner auf dem neuesten Patchstand und ein User nicht und beim User crasht es. Muss ich als Programmierer alle möglichen Updates von BS-Komponenten ausprobieren um ggf sicherzustellen, dass eine Ressource korrekt verarbeitet werden kann?
    Und woher soll ich als Programmierer wissen, dass nicht die Fragmentierung des Large Object Heap dazu führt, dass ich meine xx MB Datei nicht laden kann bzw es eine Out-Of-Memory Ex gibt?
    @ErfinderDesRades: Nein, mit Debugging ist bei mir das Debugging gemeint, das man mit F5 starten kann.
    Aber im Designer hatte ich das auch schon des öfteren (in Verbindung mit UserControls).
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

    Sinnvolle Fehlerbehandlung

    Bei IO-Vorgängen ist eine ordentliche Fehlerbehandlung wichtig,
    Da es sonst sogar zu Programmabstürzen während der Ausführung kommen kann.

    VB.NET-Quellcode

    1. Sub OrdnerAnlegen_DateiOeffnen()
    2. ' Neuen Ordner namens "Test0" erstellen
    3. Try
    4. My.Computer.FileSystem.CreateDirectory("Test0")
    5. CurDir = "Test0"
    6. Try
    7. Process.Start("Datei_im_Ordner_Test0.exe")
    8. Catch ex0 As Exception
    9. Messagebox.Show("Die Datei im Ordner Test0 konnte nicht geöffnet werden..")
    10. End Try
    11. Catch ex As Exception
    12. MessageBox.Show("Der Ordner Test0 konnte nicht erstellt werden..")
    13. End Try
    Das soll man übrigens nicht machen.
    Nicht den Basistypen "Exception" fangen, sondern nur Ableitungen wie PermissionDeniedException oder FileNotFoundException. So kann man auch eine passendere Fehlermeldung ausgeben. ;)

    Außerdem: Warum verschachteln?

    Bei solchen Sachen hilft FxCop sowie die MSDN-Dokumentation, in der aufgelistet ist, welche Exceptions bei welchen Funktionen auftreten können.
    msdn.microsoft.com/en-us/library/bb429476(v=vs.80).aspx
    Von meinem iPhone gesendet
    Zu dem GDI+: wenn man im Paint Event zum Beispiel einen Index OutOfRange hat, wird bei mir kein Fehler gezeigt, sondern das rote Kreuz gezeichnet. Das werd ich aber morgen mal testen. Ist auch schon länger her, dass ich das das letzte Mal hatte

    Skybird schrieb:

    Das sind ja Ubisoftmethoden hier !

    Folgendes Szenario:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    3. Dim datPoint() As Point = {New Point(6, 8)}
    4. e.Graphics.DrawPolygon(Pens.Black, datPoint)
    5. End Sub
    6. End Class


    Folgendes Ergebnis:



    Nun dieser Code:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    3. Try
    4. Dim datPoint() As Point = {New Point(6, 8)}
    5. e.Graphics.DrawPolygon(Pens.Black, datPoint)
    6. Catch ex As Exception
    7. MsgBox(ex.ToString())
    8. End Try
    9. End Sub
    10. End Class


    Ergebnis:



    Wie man sieht, kann man damit sehr leicht sehen, wo der Fehler geworfen wird. Dieses Beispiel ist zwar ziemlich trivial, aber so geht das mit allen GDI+ Fehlern

    Skybird schrieb:

    Das sind ja Ubisoftmethoden hier !