Frage

Ich weiß also, dass Try/Catch einen gewissen Overhead verursacht und daher keine gute Möglichkeit ist, den Prozessfluss zu steuern, aber woher kommt dieser Overhead und welche tatsächlichen Auswirkungen hat er?

War es hilfreich?

Lösung

Ich bin kein Experte für Sprachimplementierungen (also nehmen Sie das mit Vorsicht), aber ich denke, einer der größten Kosten besteht darin, den Stapel abzuwickeln und für die Stapelüberwachung zu speichern.Ich vermute, dass dies nur passiert, wenn die Ausnahme ausgelöst wird (aber ich weiß es nicht), und wenn ja, wären dies jedes Mal, wenn eine Ausnahme ausgelöst wird, angemessen große versteckte Kosten ...Es ist also nicht so, dass Sie einfach von einer Stelle im Code zur anderen springen, es ist viel los.

Ich glaube nicht, dass es ein Problem darstellt, solange Sie Ausnahmen für AUSSERGEWÖHNLICHES Verhalten verwenden (also nicht Ihren typischen, erwarteten Weg durch das Programm).

Andere Tipps

Drei Punkte sind hier anzumerken:

  • Erstens führt die tatsächliche Verwendung von Try-Catch-Blöcken in Ihrem Code nur zu geringen oder KEINEN Leistungseinbußen.Dies sollte keine Rolle spielen, wenn Sie versuchen, sie in Ihrer Bewerbung zu vermeiden.Der Leistungseinbruch kommt nur zum Tragen, wenn eine Ausnahme ausgelöst wird.

  • Wenn eine Ausnahme zusätzlich zu den von anderen erwähnten Stapelabwicklungsvorgängen usw. ausgelöst wird, sollten Sie sich darüber im Klaren sein, dass eine ganze Reihe laufzeit-/reflexionsbezogener Dinge passieren, um die Mitglieder der Ausnahmeklasse zu füllen, z. B. den Stack-Trace Objekt und die verschiedenen Typmitglieder usw.

  • Ich glaube, dass dies einer der Gründe ist, warum der allgemeine Ratschlag lautet, die Ausnahme erneut auszulösen throw; Anstatt die Ausnahme erneut auszulösen oder eine neue zu erstellen, da in diesen Fällen alle Stapelinformationen erneut erfasst werden, während beim einfachen Auslösen alle Informationen erhalten bleiben.

Fragen Sie sich nach dem Mehraufwand bei der Verwendung von try/catch/finally, wenn keine Ausnahmen ausgelöst werden, oder nach dem Mehraufwand bei der Verwendung von Ausnahmen zur Steuerung des Prozessflusses?Letzteres ähnelt in gewisser Weise der Verwendung einer Dynamitstange zum Anzünden der Geburtstagskerze eines Kleinkindes, und der damit verbundene Aufwand fällt in die folgenden Bereiche:

  • Sie können mit weiteren Cache-Fehlern rechnen, da die ausgelöste Ausnahme auf residente Daten zugreift, die sich normalerweise nicht im Cache befinden.
  • Sie können mit weiteren Seitenfehlern rechnen, da die ausgelöste Ausnahme auf nicht residenten Code und Daten zugreift, die normalerweise nicht im Arbeitssatz Ihrer Anwendung enthalten sind.

    • Das Auslösen der Ausnahme erfordert beispielsweise, dass die CLR den Speicherort der „finally“- und „catch“-Blöcke basierend auf der aktuellen IP und der Rückgabe-IP jedes Frames ermittelt, bis die Ausnahme behandelt wird, plus dem Filterblock.
    • zusätzlicher Bauaufwand und Namensauflösung zur Erstellung der Frames für Diagnosezwecke, inklusive Auslesen von Metadaten etc.
    • Beide der oben genannten Elemente greifen normalerweise auf „kalten“ Code und Daten zu, sodass Hardpage-Fehler wahrscheinlich sind, wenn überhaupt Speicherdruck vorliegt:

      • Die CLR versucht, Code und Daten, die nur selten verwendet werden, weit entfernt von Daten zu platzieren, die häufig verwendet werden, um die Lokalität zu verbessern. Das wirkt sich also negativ aus, weil Sie das Kalte dazu zwingen, heiß zu sein.
      • Die Kosten für etwaige Hardpage-Fehler werden alles andere in den Schatten stellen.
  • Typische Fangsituationen sind oft tiefgreifend, daher werden die oben genannten Effekte tendenziell verstärkt (was die Wahrscheinlichkeit von Seitenfehlern erhöht).

Die tatsächliche Auswirkung der Kosten kann stark variieren, je nachdem, was zu diesem Zeitpunkt sonst noch in Ihrem Code vor sich geht.Jon Skeet hat einen gute Zusammenfassung hier, mit einigen nützlichen Links.Ich stimme eher seiner Aussage zu, dass, wenn Sie an den Punkt kommen, an dem Ausnahmen Ihre Leistung erheblich beeinträchtigen, Sie Probleme bei der Verwendung von Ausnahmen haben, die über die reine Leistung hinausgehen.

Meiner Erfahrung nach besteht der größte Aufwand darin, tatsächlich eine Ausnahme auszulösen und zu behandeln.Ich habe einmal an einem Projekt gearbeitet, bei dem Code ähnlich dem folgenden verwendet wurde, um zu überprüfen, ob jemand das Recht hatte, ein Objekt zu bearbeiten.Diese HasRight()-Methode wurde überall in der Präsentationsebene verwendet und oft für Hunderte von Objekten aufgerufen.

bool HasRight(string rightName, DomainObject obj) {
  try {
    CheckRight(rightName, obj);
    return true;
  }
  catch (Exception ex) {
    return false;
  }
}

void CheckRight(string rightName, DomainObject obj) {
  if (!_user.Rights.Contains(rightName))
    throw new Exception();
}

Als die Testdatenbank mit Testdaten gefüllt wurde, führte dies zu einer deutlich sichtbaren Verlangsamung beim Öffnen neuer Formulare usw.

Also habe ich es wie folgt umgestaltet, was - nach späteren Quick-and-Dirty-Messungen - etwa zwei Größenordnungen schneller ist:

bool HasRight(string rightName, DomainObject obj) {
  return _user.Rights.Contains(rightName);
}

void CheckRight(string rightName, DomainObject obj) {
  if (!HasRight(rightName, obj))
    throw new Exception();
}

Kurz gesagt ist die Verwendung von Ausnahmen im normalen Prozessablauf etwa zwei Größenordnungen langsamer als die Verwendung eines ähnlichen Prozessablaufs ohne Ausnahmen.

Ganz zu schweigen davon, dass es sich auf das Gesamtverhalten der Anwendung auswirken kann, wenn es sich um eine häufig aufgerufene Methode handelt.
Beispielsweise halte ich die Verwendung von Int32.Parse in den meisten Fällen für eine schlechte Praxis, da es Ausnahmen für etwas auslöst, das andernfalls leicht abgefangen werden kann.

Um also alles abzuschließen, was hier geschrieben wurde:
1) Verwenden Sie try..catch-Blöcke, um unerwartete Fehler abzufangen – fast ohne Leistungseinbußen.
2) Verwenden Sie keine Ausnahmen für ausgenommene Fehler, wenn Sie dies vermeiden können.

Ich habe vor einiger Zeit einen Artikel darüber geschrieben, weil es damals viele Leute gab, die danach fragten.Sie finden ihn und den Testcode unter http://www.blackwasp.co.uk/SpeedTestTryCatch.aspx.

Das Ergebnis ist, dass ein Try/Catch-Block nur einen geringen Overhead verursacht, der jedoch so gering ist, dass er ignoriert werden sollte.Wenn Sie jedoch Try/Catch-Blöcke in Schleifen ausführen, die millionenfach ausgeführt werden, sollten Sie erwägen, den Block nach Möglichkeit außerhalb der Schleife zu verschieben.

Das Hauptleistungsproblem bei Try/Catch-Blöcken besteht darin, wann tatsächlich eine Ausnahme abgefangen wird.Dies kann zu einer spürbaren Verzögerung Ihrer Bewerbung führen.Wenn etwas schief geht, erkennen die meisten Entwickler (und viele Benutzer) die Pause natürlich als eine Ausnahme, die bald eintreten wird!Der Schlüssel liegt hier darin, die Ausnahmebehandlung nicht für normale Vorgänge zu verwenden.Wie der Name schon sagt, sind sie außergewöhnlich und Sie sollten alles tun, um zu verhindern, dass sie geworfen werden.Sie sollten sie nicht als Teil des erwarteten Ablaufs eines ordnungsgemäß funktionierenden Programms verwenden.

Ich machte einen Blog-Eintrag zu diesem Thema letztes Jahr.Hör zu.Unterm Strich fallen für einen Try-Block fast keine Kosten an, wenn keine Ausnahme auftritt – und auf meinem Laptop dauerte eine Ausnahme etwa 36 μs.Das ist möglicherweise weniger als erwartet, aber bedenken Sie, dass diese Ergebnisse auf einem flachen Stapel lagen.Außerdem sind erste Ausnahmen sehr langsam.

Es ist wesentlich einfacher, Code zu schreiben, zu debuggen und zu warten, der frei von Compiler-Fehlermeldungen, Warnmeldungen der Codeanalyse und routinemäßig akzeptierten Ausnahmen ist (insbesondere Ausnahmen, die an einer Stelle ausgelöst und an einer anderen akzeptiert werden).Da es einfacher ist, ist der Code im Durchschnitt besser geschrieben und weniger fehlerhaft.

Für mich ist dieser Programmier- und Qualitätsaufwand das Hauptargument gegen die Verwendung von Try-Catch für den Prozessablauf.

Der Computeraufwand durch Ausnahmen ist im Vergleich dazu unbedeutend und im Hinblick auf die Fähigkeit der Anwendung, reale Leistungsanforderungen zu erfüllen, normalerweise gering.

Im Gegensatz zu allgemein akzeptierten Theorien try/catch kann erhebliche Auswirkungen auf die Leistung haben, und zwar unabhängig davon, ob eine Ausnahme ausgelöst wird oder nicht!

  1. Es deaktiviert einige automatische Optimierungen (absichtlich), und in einigen Fällen injiziert Debuggen Code, wie Sie es von einem erwarten können Debugging-Hilfe.Es wird immer Leute geben, die mir in diesem Punkt nicht zustimmen, aber die Sprache erfordert es und die Zerlegung zeigt es, also beziehen sich diese Leute auf die Definition des Wörterbuchs wahnhaft.
  2. Dies kann sich negativ auf die Wartung auswirken. Dies ist eigentlich das wichtigste Problem hier, aber da meine letzte Antwort (die sich fast ausschließlich darauf konzentrierte) gelöscht wurde, werde ich versuchen, mich auf das weniger wichtige Problem (die Mikrooptimierung) zu konzentrieren und nicht auf das wichtigere Problem ( die Makrooptimierung).

Ersteres wurde im Laufe der Jahre in einigen Blog-Beiträgen von Microsoft-MVPs behandelt, und ich vertraue darauf, dass Sie sie leicht finden können, aber StackOverflow kümmert sich darum so viel um Inhalt Deshalb werde ich einige davon verlinken Füllstoff Beweis:

Es gibt auch diese Antwort Dies zeigt den Unterschied zwischen zerlegtem Code mit und ohne Verwendung try/catch.

Es scheint so offensichtlich, dass es da ist Ist Ein Overhead, der bei der Codegenerierung offensichtlich zu beobachten ist, und dieser Overhead scheint sogar von Leuten anerkannt zu werden, die Microsoft wertschätzt!Dennoch bin ich, das Internet wiederholen...

Ja, es gibt Dutzende zusätzlicher MSIL-Anweisungen für eine triviale Codezeile, und das deckt nicht einmal die deaktivierten Optimierungen ab, sodass es sich technisch gesehen um eine Mikrooptimierung handelt.


Ich habe vor Jahren eine Antwort gepostet, die gelöscht wurde, da sie sich auf die Produktivität von Programmierern (die Makrooptimierung) konzentrierte.

Dies ist bedauerlich, da keine Einsparung einiger weniger Nanosekunden CPU-Zeit hier und da viele Stunden manueller Optimierung durch Menschen ausgleichen kann.Wofür zahlt Ihr Chef mehr:eine Stunde Ihrer Zeit oder eine Stunde bei laufendem Computer?An welchem ​​Punkt ziehen wir den Stecker und geben zu, dass es Zeit ist, es einfach zu tun? Kaufen Sie einen schnelleren Computer?

Das sollten wir ganz klar tun Optimierung unserer Prioritäten, nicht nur unser Code!In meiner letzten Antwort habe ich auf die Unterschiede zwischen zwei Codeausschnitten eingegangen.

Benutzen try/catch:

int x;
try {
    x = int.Parse("1234");
}
catch {
    return;
}
// some more code here...

Wird nicht verwendet try/catch:

int x;
if (int.TryParse("1234", out x) == false) {
    return;
}
// some more code here

Bedenken Sie aus der Perspektive eines Wartungsentwicklers, dass es wahrscheinlicher ist, dass Sie Ihre Zeit verschwenden, wenn Sie sich nicht mit der Profilerstellung/Optimierung (siehe oben) befassen, was wahrscheinlich nicht einmal notwendig wäre, wenn es das nicht gäbe try/catch Problem, dann beim Scrollen durch den Quellcode ...Eines davon enthält vier zusätzliche Zeilen mit Standardmüll!

Wenn immer mehr Felder in eine Klasse eingeführt werden, häuft sich dieser gesamte Müll (sowohl im Quellcode als auch im disassemblierten Code) weit über ein vernünftiges Maß hinaus an.Vier zusätzliche Zeilen pro Feld, und es sind immer die gleichen Zeilen ...Wurde uns nicht beigebracht, Wiederholungen zu vermeiden?Ich nehme an, wir könnten das verstecken try/catch hinter einer selbstgebrauten Abstraktion, aber...dann könnten wir genauso gut Ausnahmen vermeiden (d. h.verwenden Int.TryParse).

Dies ist nicht einmal ein komplexes Beispiel;Ich habe Versuche gesehen, neue Klassen zu instanziieren try/catch.Bedenken Sie, dass der gesamte Code im Konstruktor dann möglicherweise von bestimmten Optimierungen ausgeschlossen wird, die andernfalls automatisch vom Compiler angewendet würden.Wie könnte man die Theorie besser aufstellen? Der Compiler ist langsam, im Gegensatz zu Der Compiler macht genau das, was ihm gesagt wird?

Angenommen, der Konstruktor löst eine Ausnahme aus und löst dadurch einen Fehler aus, dann muss der schlechte Wartungsentwickler ihn aufspüren.Das ist vielleicht keine so einfache Aufgabe, denn im Gegensatz zum Spaghetti-Code des gehe zu Alptraum, try/catch kann zu Unordnung führen drei Dimensionen, da es nicht nur in andere Teile derselben Methode, sondern auch in andere Klassen und Methoden im Stapel nach oben wandern könnte, die alle vom Wartungsentwickler beobachtet werden, der harte Weg!Dennoch wird uns gesagt, dass „goto gefährlich“ sei, heh!

Am Ende erwähne ich, try/catch hat seinen Vorteil, nämlich, Es dient dazu, Optimierungen zu deaktivieren!Es ist, wenn man so will, ein Debugging-Hilfe!Dafür wurde es entwickelt und genau dafür sollte es verwendet werden ...

Ich denke, das ist auch ein positiver Punkt.Es kann verwendet werden, um Optimierungen zu deaktivieren, die andernfalls sichere und vernünftige Nachrichtenübermittlungsalgorithmen für Multithread-Anwendungen lahmlegen könnten, und um mögliche Race-Bedingungen abzufangen ;) Das ist ungefähr das einzige Szenario, das ich mir für die Verwendung von Try/Catch vorstellen kann.Auch das hat Alternativen.


Was Optimierungen bewirken try, catch Und finally deaktivieren?

A.K.A

Wie sind try, catch Und finally nützlich als Debugging-Hilfsmittel?

Sie sind Schreibbarrieren.Das kommt aus dem Standard:

12.3.3.13 Try-Catch-Anweisungen

Für eine Aussage stmt der Form:

try try-block
catch ( ... ) catch-block-1
... 
catch ( ... ) catch-block-n
  • Der definitive Zuweisungsstatus von v am Anfang von Try-Block ist derselbe wie der definitive Zuweisungsstatus von v am Anfang von stmt.
  • Der definitive Zuweisungsstatus von v am Anfang von Catch-Block-i (für jeden ich) ist derselbe wie der definitive Zuweisungsstatus von v am Anfang von stmt.
  • Der definitive Zuweisungsstatus von v am Endpunkt von stmt wird definitiv zugewiesen, wenn (und nur dann) v wird definitiv am Endpunkt von zugewiesen Try-Block Und jeder Catch-Block-i (für jeden ich von 1 bis N).

Mit anderen Worten, jeweils am Anfang try Stellungnahme:

  • Alle Zuweisungen zu sichtbaren Objekten vor dem Betreten des try Die Anweisung muss vollständig sein, was zunächst eine Thread-Sperre erfordert, was sie zum Debuggen von Rennbedingungen nützlich macht!
  • Der Compiler darf nicht:
    • Beseitigen Sie nicht verwendete Variablenzuweisungen, denen zuvor definitiv zugewiesen wurde try Stellungnahme
    • irgendetwas davon neu organisieren oder zusammenführen innere Aufgaben (d. h.siehe meinen ersten Link, falls Sie dies noch nicht getan haben).
    • Heben Sie Zuweisungen über diese Barriere, um Zuweisungen an eine Variable zu verzögern, von der Sie wissen, dass sie erst später (wenn überhaupt) verwendet werden, oder um spätere Zuweisungen präventiv nach vorne zu verschieben, um andere Optimierungen zu ermöglichen ...

Für beide gilt eine ähnliche Geschichte catch Stellungnahme;nehme an, in deinem try Anweisung (oder einen Konstruktor oder eine Funktion, die sie aufruft usw.), die Sie dieser ansonsten sinnlosen Variablen zuweisen (sagen wir garbage=42;), kann der Compiler diese Anweisung nicht entfernen, egal wie irrelevant sie für das beobachtbare Verhalten des Programms ist.Die Aufgabe muss vorhanden sein vollendet Vor dem catch Block eingegeben wird.

Für das, was es wert ist, finally erzählt ein ähnliches erniedrigend Geschichte:

12.3.3.14 Try-finally-Anweisungen

Für ein versuchen Stellungnahme stmt der Form:

try try-block
finally finally-block

• Der definitive Zuweisungsstatus von v am Anfang von Try-Block ist derselbe wie der definitive Zuweisungsstatus von v am Anfang von stmt.
• Der definitive Zuweisungsstatus von v am Anfang von endlich-blockieren ist derselbe wie der definitive Zuweisungsstatus von v am Anfang von stmt.
• Der definitive Zuweisungsstatus von v am Endpunkt von stmt wird definitiv zugewiesen, wenn (und nur dann) entweder:Ö v wird definitiv am Endpunkt von zugewiesen Try-BlockÖ v wird definitiv am Endpunkt von zugewiesen endlich-blockierenWenn eine Kontrollflussübertragung (z. B. eine gehe zu Aussage) gemacht wird, die im Inneren beginnt Try-Block, und endet außerhalb von Try-Block, Dann v gilt bei dieser Kontrollflussübertragung auch als definitiv zugewiesen, wenn v wird definitiv am Endpunkt von zugewiesen endlich-blockieren.(Dies ist kein einziges Wenn-Wenn v aus einem anderen Grund bei dieser Kontrollflussübertragung definitiv zugewiesen ist, gilt es dennoch als definitiv zugewiesen.)

12.3.3.15 Try-Catch-finally-Anweisungen

Definitive Zuordnungsanalyse für a versuchen-fangen-Endlich Aussage des Formulars:

try try-block
catch ( ... ) catch-block-1
... 
catch ( ... ) catch-block-n
finally finally-block

erfolgt so, als ob die Aussage a wäre versuchen-Endlich Erklärung, die a versuchen-fangen Stellungnahme:

try { 
    try   
    try-block
    catch ( ... ) catch-block-1
    ...   
    catch ( ... ) catch-block-n
} 
finally finally-block

Ich mag Hafthors wirklich Blogeintrag, und um dieser Diskussion meinen Beitrag zu leisten, möchte ich sagen, dass es für mich immer einfach war, den DATA LAYER nur einen Ausnahmetyp (DataAccessException) auslösen zu lassen.Auf diese Weise weiß mein BUSINESS LAYER, welche Ausnahme zu erwarten ist, und fängt sie ab.Abhängig von weiteren Geschäftsregeln (d. h.Wenn mein Geschäftsobjekt am Workflow usw. teilnimmt, kann ich eine neue Ausnahme (BusinessObjectException) auslösen oder ohne erneutes Auslösen fortfahren.

Ich würde sagen, zögern Sie nicht, try..catch zu verwenden, wann immer es nötig ist, und setzen Sie es mit Bedacht ein!

Diese Methode nimmt beispielsweise an einem Workflow teil ...

Kommentare?

public bool DeleteGallery(int id)
{
    try
    {
        using (var transaction = new DbTransactionManager())
        {
            try
            {
                transaction.BeginTransaction();

                _galleryRepository.DeleteGallery(id, transaction);
                _galleryRepository.DeletePictures(id, transaction);

                FileManager.DeleteAll(id);

                transaction.Commit();
            }
            catch (DataAccessException ex)
            {
                Logger.Log(ex);
                transaction.Rollback();                        
                throw new BusinessObjectException("Cannot delete gallery. Ensure business rules and try again.", ex);
            }
        }
    }
    catch (DbTransactionException ex)
    {
        Logger.Log(ex);
        throw new BusinessObjectException("Cannot delete gallery.", ex);
    }
    return true;
}

Wir können in Programming Languages ​​Pragmatics von Michael L. lesen.Scott, dass die heutigen Compiler im Normalfall, also wenn keine Ausnahmen auftreten, keinen Overhead verursachen.Daher wird jede Arbeit in der Kompilierzeit erstellt.Wenn jedoch zur Laufzeit eine Ausnahme ausgelöst wird, muss der Compiler eine binäre Suche durchführen, um die richtige Ausnahme zu finden. Dies geschieht bei jedem neuen ausgelösten Fehler.

Aber Ausnahmen sind Ausnahmen und diese Kosten sind völlig akzeptabel.Wenn Sie versuchen, die Ausnahmebehandlung ohne Ausnahmen durchzuführen und stattdessen Rückgabefehlercodes zu verwenden, benötigen Sie wahrscheinlich eine if-Anweisung für jede Unterroutine, was zu einem echten Echtzeit-Overhead führt.Sie wissen, dass eine if-Anweisung in einige Assembleranweisungen umgewandelt wird, die jedes Mal ausgeführt werden, wenn Sie Ihre Unterroutinen eingeben.

Tut mir leid wegen meines Englisch, ich hoffe, es hilft dir.Diese Informationen basieren auf dem zitierten Buch. Weitere Informationen finden Sie in Kapitel 8.5 Ausnahmebehandlung.

Lassen Sie uns einen der größtmöglichen Kosten eines Try/Catch-Blocks analysieren, wenn er dort verwendet wird, wo er nicht verwendet werden sollte:

int x;
try {
    x = int.Parse("1234");
}
catch {
    return;
}
// some more code here...

Und hier ist das ohne Try/Catch:

int x;
if (int.TryParse("1234", out x) == false) {
    return;
}
// some more code here

Wenn man den unbedeutenden Leerraum nicht mitzählt, könnte man feststellen, dass diese beiden äquivalenten Codeteile fast genau die gleiche Länge in Bytes haben.Letzteres enthält 4 Byte weniger Einrückung.Ist das etwas schlechtes?

Um das Ganze noch schlimmer zu machen, entscheidet sich ein Schüler für eine Schleife, während die Eingabe als int geparst werden kann.Die Lösung ohne Try/Catch könnte etwa so aussehen:

while (int.TryParse(...))
{
    ...
}

Aber wie sieht das bei der Verwendung von Try/Catch aus?

try {
    for (;;)
    {
        x = int.Parse(...);
        ...
    }
}
catch
{
    ...
}

Try/Catch-Blöcke sind magische Möglichkeiten, Einrückungen zu verschwenden, und wir wissen immer noch nicht einmal, warum sie fehlgeschlagen sind!Stellen Sie sich vor, wie sich die Person, die das Debugging durchführt, fühlt, wenn der Code auch nach einem schwerwiegenden logischen Fehler weiter ausgeführt wird, anstatt mit einem schönen, offensichtlichen Ausnahmefehler anzuhalten.Try/Catch-Blöcke sind die Datenvalidierung/-bereinigung eines faulen Mannes.

Einer der geringeren Kosten besteht darin, dass Try/Catch-Blöcke tatsächlich bestimmte Optimierungen deaktivieren: http://msmvps.com/blogs/peterritchie/archive/2007/06/22/performance-implications-of-try-catch-finally.aspx.Ich denke, das ist auch ein positiver Punkt.Es kann verwendet werden, um Optimierungen zu deaktivieren, die andernfalls sichere und vernünftige Nachrichtenübermittlungsalgorithmen für Multithread-Anwendungen lahmlegen könnten, und um mögliche Race-Bedingungen abzufangen ;) Das ist ungefähr das einzige Szenario, das ich mir für die Verwendung von Try/Catch vorstellen kann.Auch das hat Alternativen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top