In .NET ist es irgendeinen Vorteil zu einem try / catch, wo der Fang nur [Duplikat] rethrows

StackOverflow https://stackoverflow.com/questions/1207172

  •  05-07-2019
  •  | 
  •  

Frage

  

Mögliche Duplizieren:
   Warum fangen und rethrow Ausnahme in C #?

Ich komme manchmal über C # Code, der wie folgt aussieht:

        try
        {
            // Some stuff
        }
        catch (Exception e)
        {
            throw e;
        }

Ich verstehe seine möglichen etwas wie protokollieren die Ausnahmemeldung zu tun und rethrow es dann. Ich spreche von einer Raste, die nur die Ausnahme rethrows. Ich habe keinen Punkt dazu sehen. Ich habe drei Fragen:

1) Gibt es irgendeinen Vorteil dieses

2) Ist diese langsam doen der Code überhaupt

3) Würde es einen Unterschied machen, wenn der catch-Block war wie folgt:

        catch (Exception)
        {
            throw;
        }
War es hilfreich?

Lösung

Dieses rethrows die genau gleiche Ausnahme:

    catch (Exception)
    {
        throw;
    }

Während diese rethrows die Ausnahme ohne den ursprünglichen Stack-Trace:

    catch (Exception e)
    {
        throw e;
    }

Es ist oft ein guter Grund für throw; wie Sie die Ausnahme anmelden können oder andere Dinge tun, bevor die Ausnahme Erneutes Auslösen. Ich bin nicht bekannt, dass gute Gründe für throw e;, wie Sie den wertvollen Stack-Trace-Daten auszulöschen.

Andere Tipps

Nicht, wenn Sie nichts anderes in dem Fang tun ... Aber das wird oft verwendet, andere Dinge in den Fängen, wie Logging, oder andere Arten von Ausnahme procesing zu tun, bevor es Erneutes Auslösen.

Ich verwende diese Technik so kann ich einen Haltepunkt auf dem Wurf setzen beim Debuggen. Manchmal entferne ich es, nachdem ich fertig bin ...

Der wesentliche Unterschied besteht darin, dass der Stack-Trace der Ausnahme geändert werden, um zu zeigen, dass sie von der Lage des Try-Catch im ersten Beispiel stammten.

Das zweite Beispiel behält den Stack-Trace.

Gibt es einen Vorteil

Im Allgemeinen nicht. All diese Muster machen wird, ist der Stack-Trace auf den Punkt des neuen Wurf zurückgesetzt. Dies wird nur machen es schwieriger für Entwickler die Ursache des Problems auf die Spur

Verlangsamt es den Code unten auf allen

Bei allen? Möglicherweise. Verlangsamen sie durch eine messbare Differenz nach unten? Nein.

Würde es einen Unterschied machen, wenn der catch-Block wie folgt ist?

Ja, das ist Fang im Wesentlichen vollständig redundant. Es wird die Ausnahme erneut auslösen, die den ursprünglichen Stack-Trace und hat keine percievable Auswirkungen auf Ihrer Anwendung erhalten.

1 - Ich sehe keinen Vorteil überhaupt. Wenn Sie nicht die Ausnahmebehandlung, lassen Sie die try / catch ab. Das andere Problem mit diesem Beispiel ist, dass Sie nicht die tatsächliche Ausnahme zu werfen, aber neu.

2 - ja -. Aber es sei denn, dies in einer großen Schleife wiederholt Code sitzen, werden Sie wahrscheinlich feststellen, wird keinen Unterschied

3 - Ja. Im ersten Beispiel sind in Unordnung Sie mit Ihrem Call-Stack. Dieses Beispiel hält den Stapel intakt durch die Ausnahme sprudelt, anstatt einen neuen zu werfen.

Wenn Sie wirklich nichts anderes zu tun, es gibt nur einen Vorteil, den ich je gefunden habe: Sie einen Haltepunkt auf der throw Zeile setzen können. Es macht es sehr spezifisch (und nicht nur brechen, wenn der Ausnahmetyp ausgelöst wird).

Ich würde das nur tun, während obwohl das Debuggen, kehren Sie dann den Code zurück.

Ich schrieb einen Schnelltest auf, um die Unterschiede zu zeigen. Hier ist der Testcode:

try
{
    var broken = int.Parse("null");
}
catch (Exception ex1)
{
    System.Diagnostics.Trace.WriteLine(ex1.ToString());
}

try
{
    try
    {
        var broken = int.Parse("null");
    }
    catch (Exception)
    {
        throw;
    }
}
catch (Exception ex2)
{
    System.Diagnostics.Trace.WriteLine(ex2.ToString());
}

try
{
    try
    {
        var broken = int.Parse("null");
    }
    catch (Exception ex3)
    {
        throw ex3;
    }
}
catch (Exception ex4)
{
    System.Diagnostics.Trace.WriteLine(ex4.ToString());
}

Ausführen dieser, erhalte ich die folgende Ausgabe:

A first chance exception of type 'System.FormatException' occurred in mscorlib.dll
System.FormatException: Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   at System.Int32.Parse(String s)
   at QuickTests.Program.Main(String[] args) in C:\Projects\Test\QuickTests\Program.cs:line 18
A first chance exception of type 'System.FormatException' occurred in mscorlib.dll
A first chance exception of type 'System.FormatException' occurred in QuickTests.exe
System.FormatException: Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   at System.Int32.Parse(String s)
   at QuickTests.Program.Main(String[] args) in C:\Projects\Test\QuickTests\Program.cs:line 33
A first chance exception of type 'System.FormatException' occurred in mscorlib.dll
A first chance exception of type 'System.FormatException' occurred in QuickTests.exe
System.FormatException: Input string was not in a correct format.
   at QuickTests.Program.Main(String[] args) in C:\Projects\Test\QuickTests\Program.cs:line 49

Sie werden bemerken, dass die ersten beiden Ausnahmen arbeiten, sind auf die gleiche Weise. Also, „werfen“; nichts so weit wie die Ausnahme ändern, die den Stapel nach oben bewegt. Allerdings „ex3 werfen;“ bewirkt, dass die gemeldete Ausnahme, anders zu sein, für die Ausnahme des Stack-Trace zu ändern.

Es ist oft schön für die Protokollierung. Auch wenn Sie das Argument in dem Wiederwurf wegzulassen dann ist es nicht ändern, um den Stack-Trace e.

Manchmal möchte man durch bestimmte Arten ermöglichen, z.B. hier ist eine spezielle Verarbeitung für alles, aber FooException:

try
{
    // ...
}
catch (FooException)
{
    throw;
}
catch (Exception ex)
{
    // handle differently, like wrap with a FooException
    throw new FooException("I pitty the Foo.", ex);
}

Klar.

Am häufigsten wollen Sie die Ausnahme loggt sein, bevor es zu werfen, und vielleicht einige Variablenwerte aus dem Verfahren aufzuzeichnen.

Nur fangen sie zu werfen, aber nicht gewinnen Sie nicht viel.

Einfach so, nein. Allerdings können Sie dies tun:

catch (Exception ex)
{
     LogException(ex);
     throw;
}

Wo LogException () ist eine benutzerdefinierte Klasse, die, ähm, protokolliert die Ausnahme oder E-Mails eine Warnung oder so etwas.

Ich denke, der Punkt, dass, um sicherzustellen, ist nur eine Art von Ausnahme ausgelöst. Es ist ein ziemlich schlechtes anti-Muster IMHO

z.

try
{
    throw XYZ();
}
catch(Exception e)
{
    throw e;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top