Frage

Ich habe dieses Problem derzeit nicht, aber man weiß nie, und Gedankenexperimente machen immer Spaß.

Ignorieren Sie die offensichtlichen Probleme, die Sie mit Ihrer Architektur haben müssten, um dies überhaupt zu versuchen, Nehmen wir an, Sie hätten einen schrecklich geschriebenen Code, der von jemand anderem entworfen wurde, und Sie müssten eine Reihe umfangreicher und unterschiedlicher Operationen im selben Codeblock ausführen, z. B.:

WidgetMaker.SetAlignment(57);
contactForm["Title"] = txtTitle.Text;
Casserole.Season(true, false);
((RecordKeeper)Session["CasseroleTracker"]).Seasoned = true;

Mit hundert multipliziert.Einige davon könnten funktionieren, andere könnten völlig schiefgehen.Was Sie benötigen, ist das C#-Äquivalent von „Bei Fehler als nächstes fortsetzen“, andernfalls werden Sie am Ende Try-Catches in den vielen Codezeilen kopieren und einfügen.

Wie würden Sie versuchen, dieses Problem anzugehen?

War es hilfreich?

Lösung

Es ist ziemlich offensichtlich, dass Sie den Code in VB.NET schreiben würden, die tatsächlich funktioniert? On Error Resume Next , und exportieren es in einer DLL C #. Alles andere ist einfach nur ein Vielfraß  für die Strafe.

Andere Tipps

public delegate void VoidDelegate();

public static class Utils
{
  public static void Try(VoidDelegate v) {
    try {
      v();
    }
    catch {}
  }
}

Utils.Try( () => WidgetMaker.SetAlignment(57) );
Utils.Try( () => contactForm["Title"] = txtTitle.Text );
Utils.Try( () => Casserole.Season(true, false) );
Utils.Try( () => ((RecordKeeper)Session["CasseroleTracker"]).Seasoned = true );

Umgestalten in einzelne, gut genannten Methoden:

AdjustFormWidgets();
SetContactTitle(txtTitle.Text);
SeasonCasserole();

Jede dieser geschützt ist angemessen.

Ich würde sagen, nichts tun .

Yup das ist richtig, nichts tun.

Sie haben eindeutig identifiziert zwei Dinge zu mir:

  1. Sie wissen, dass die Architektur borked ist.
  2. Es gibt eine Tonne von diesem Mist.

Ich sage:

  • Sie nichts.
  • Fügen Sie eine globale Fehlerbehandlung Sie eine E-Mail es Boom geht jedes Mal zu senden.
  • Warten Sie, bis etwas umfällt (oder nicht einen Test)
  • Richtig, dass (Refactoring als notwendig im Rahmen der Seite ).
  • Wiederholen Sie jedes Mal, wenn ein Problem auftritt.

Sie haben dies in kürzester Zeit gelöscht, wenn es so schlimm ist. Ja, ich weiß, es klingt sucky und Sie können Ihre Haare mit Fehlerbehebungen Strang ziehen zu beginnen, aber es ermöglicht es Ihnen, auf fixieren den Bedürftigen / fehlerhaftem Code vor die (große) Menge von Code das kann tatsächlich arbeiten sein , egal wie beschissen es aussieht.

Wenn Sie den Krieg zu gewinnen beginnen, werden Sie einen besseren Griff auf dem Code haben (wegen all Ihre Refactoring) Sie eine bessere Idee für einen Siegerentwurf für sie haben wird ..

Der Versuch, alles in Luftpolsterfolie zu wickeln ist wahrscheinlich nur ein lange dauern werde zu tun, und Sie werden noch nicht näher sein, die Probleme zu beheben.

Schnell scheitern

Um es näher zu erläutern: Ich denke, ich stelle die Frage in Frage.Wenn eine Ausnahme ausgelöst wird, warum soll Ihr Code dann einfach so fortgesetzt werden, als ob nichts passiert wäre?Entweder erwarten Sie in bestimmten Situationen Ausnahmen. In diesem Fall schreiben Sie einen Try-Catch-Block um diesen Code und behandeln ihn, oder es liegt ein unerwarteter Fehler vor. In diesem Fall sollten Sie es vorziehen, dass Ihre Anwendung abbricht, erneut versucht oder fehlschlägt.Nicht weitermachen wie ein verwundeter Zombie, der „Gehirne“ stöhnt.

Dies ist eines der Dinge, die einen Prä-Prozessor aufweist, ist nützlich für die. Sie könnten einen Makro definieren, die Ausnahmen, dann mit einem schnellen Skript hinzufügen, dass Makro auf alle Zeilen schluckt.

Also, wenn diese C ++ sind, können Sie so etwas tun könnten:

#define ATTEMPT(x) try { x; } catch (...) { }
// ...
ATTEMPT(WidgetMaker.SetAlignment(57));
ATTEMPT(contactForm["Title"] = txtTitle.Text);
ATTEMPT(Casserole.Season(true, false));
ATTEMPT(((RecordKeeper)Session["CasseroleTracker"]).Seasoned = true);

Leider nicht viele Sprachen scheinen eine Präprozessor wie C / C ++ tat aufzunehmen.

Sie können Ihren eigenen Präprozessor erstellen und als Pre-Build-Schritt hinzuzufügen. Wenn Sie völlig fühlte sich an wie die Automatisierung könnte man wahrscheinlich einen Präprozessor schreiben, den eigentlichen Code-Datei übernehmen würde und die try / catch Sachen in der auf seine eigenen hinzufügen (so haben Sie nicht jene VERSUCH () blockiert, um den Code manuell hinzufügen) . Sicherstellen, dass es nur die Linien verändert es angenommen hat, obwohl schwer sein könnte (haben Variablendeklarationen zu überspringen, Schleifenkonstrukte, etc, dass Sie den Build nicht brechen).

Aber ich denke, diese schrecklichen Ideen sind und soll nie geschehen, aber die Frage gestellt wurde. :)

Wirklich, Sie sollten nicht immer das tun. Sie müssen herausfinden, was den Fehler verursacht und beheben. Schlucken / ignorieren Fehler ist eine schlechte Sache zu tun, so dass ich denke, die richtig beantworten hier ist „um den Fehler zu beheben, kann es nicht ignorieren!“. :)

On Error Resume Next ist eine wirklich schlechte Idee in der C # Welt. Auch würde das Hinzufügen der äquivalent On Error Resume Next tatsächlich zu helfen. Alles, was es tun würde, ist, dass Sie in einem schlechten Zustand verlassen, der Datenverlust subtile Fehler verursachen könnte und Korruption möglicherweise Daten.

Aber der Fragesteller seine Schuld zu geben, könnten Sie einen globalen Handler hinzufügen und die Target überprüfen, um zu sehen, welche Methode borked. Dann wissen Sie könnten zumindest was Linie es borked auf. Der nächste Teil wäre zu versuchen, herauszufinden, wie die „nächste Anweisung“ auf die gleiche Weise einstellt die Debugger es tut. Hoffentlich ist Ihr Stack wird nicht an dieser Stelle abgewickelt oder Sie können es neu erstellen, aber es ist auf jeden Fall einen Versuch wert. Da jedoch dieser Ansatz würde der Code jedes Mal im Debug-Modus ausgeführt werden, so dass Sie Ihre Debug-Symbole enthalten haben.

Als jemand erwähnt wurde, ermöglicht VB dies. Wie wäre es die gleiche Weise in C # zu tun? Geben Sie treuen Reflektor:

Dieses:

Sub Main()
    On Error Resume Next

    Dim i As Integer = 0

    Dim y As Integer = CInt(5 / i)


End Sub

Verschiebt in diese:

public static void Main()
{
    // This item is obfuscated and can not be translated.
    int VB$ResumeTarget;
    try
    {
        int VB$CurrentStatement;
    Label_0001:
        ProjectData.ClearProjectError();
        int VB$ActiveHandler = -2;
    Label_0009:
        VB$CurrentStatement = 2;
        int i = 0;
    Label_000E:
        VB$CurrentStatement = 3;
        int y = (int) Math.Round((double) (5.0 / ((double) i)));
        goto Label_008F;
    Label_0029:
        VB$ResumeTarget = 0;
        switch ((VB$ResumeTarget + 1))
        {
            case 1:
                goto Label_0001;

            case 2:
                goto Label_0009;

            case 3:
                goto Label_000E;

            case 4:
                goto Label_008F;

            default:
                goto Label_0084;
        }
    Label_0049:
        VB$ResumeTarget = VB$CurrentStatement;
        switch (((VB$ActiveHandler > -2) ? VB$ActiveHandler : 1))
        {
            case 0:
                goto Label_0084;

            case 1:
                goto Label_0029;
        }
    }
    catch (object obj1) when (?)
    {
        ProjectData.SetProjectError((Exception) obj1);
        goto Label_0049;
    }
Label_0084:
    throw ProjectData.CreateProjectError(-2146828237);
Label_008F:
    if (VB$ResumeTarget != 0)
    {
        ProjectData.ClearProjectError();
    }
}

Geben Sie den Code ein. Versuchen Sie Sätze von Aussagen zu finden, die logisch voneinander abhängig sind, so dass, wenn man nicht dann die Nächsten keinen Sinn machen, und hive sie in ihre eigenen Funktionen aus und legte versuchen Beifänge um sie, wenn Sie das Ergebnis ignoriert werden sollen dass und weiter.

Dies kann Ihnen helfen, die Stücke in identifing, die die meisten Probleme haben.

@ JB König Danke, dass du mich erinnert hast. Der Logging-Anwendung Block ein Instrumentation Ereignis hat, die verwendet werden kann Ereignisse zu verfolgen, können Sie weitere Informationen über die MS Enterprise Library-Dokumentation finden.

Using (New InstEvent)
<series of statements> 
End Using

Alle Schritte in dieser Verwendung wird in einer Protokolldatei zurückgeführt werden, und Sie können das sehen analysieren, in dem die Protokollpausen (ex geworfen) und id die hohen Straftäter.

Refactoring ist wirklich die beste Wahl, aber wenn Sie viel haben, dies kann Ihnen helfen, die schlimmsten Übeltäter identifizieren.

Sie könnte Nutzung gehe, aber es ist immer noch chaotisch.

Ich wollte eigentlich eine Art einzigen Anweisung try-catch für eine Weile. Es wäre in bestimmten Fällen hilfreich sein, wie das Hinzufügen von Logging-Code oder etwas, das Sie nicht wollen, den Hauptprogrammablauf zu unterbrechen, wenn es fehlschlägt.

Ich vermute, dass etwas mit einigen der Funktionen mit Linq assoziiert getan werden könnte, aber nicht wirklich Zeit in es im Moment zu suchen. Wenn Sie nur einen Weg finden, könnte eine Erklärung als eine anonyme Funktion zu wickeln, dann benutzen Sie ein anderes zu rufen, dass innerhalb eines Try-Catch-Block würde es funktionieren ... aber nicht sicher, ob das möglich ist nur noch.

Wenn Sie die Compiler bekommen können Ihnen einen Ausdruck Baum für diesen Code zu geben, dann könnte man diesen Ausdruck Baum ändern, indem jede Anweisung mit einem neuen Try-Catch-Block zu ersetzen, die die ursprüngliche Anweisung wickelt. Das ist nicht so weit hergeholt, wie es klingt; LINQ, erworben C # die Fähigkeit, Lambda-Ausdrücke als Ausdruck Bäume zu erfassen, die in Benutzercode zur Laufzeit manipuliert werden können.

Dieser Ansatz ist heute nicht möglich, mit .NET 3.5 - wenn auch aus keinem anderen Grunde, als das Fehlen einer „versuchen“ Anweisung in System.Linq.Expressions. Aber es kann sehr gut in einer zukünftigen Version von C # lebensfähig sein, wenn die Zusammenführung der DLR und LINQ Ausdruck Bäume abgeschlossen ist.

Warum nicht die Reflexion in c # verwenden? Sie könnten eine Klasse erstellen, die für das, was auf den Code und die Verwendung Linie # s als Hinweis spiegelt sich in jedem einzelnen try / catch-Block zu setzen. Dies hat einige Vorteile:

  1. Die etwas weniger hässlich wie sie nicht wirklich Sie Ihren Quellcode mangle benötigen und Sie können es nur während des Debug-Modi verwenden.
  2. Sie lernen etwas interessanten c #, während es zu implementieren.

Ich würde jedoch gegen irgendetwas davon empfehlen, es sei denn natürlich, Sie über maintance von someelses Arbeit einnehmen, und Sie müssen einen Griff auf die Ausnahmen erhalten, damit Sie sie beheben können. Könnte Spaß machen, obwohl zu schreiben.

Spaß Frage; sehr schrecklich.

Es wäre schön, wenn Sie ein Makro verwenden könnte. Aber das ist C # gestrahlt, so dass Sie es mit etwas Präprozessor Arbeit oder einem externen Werkzeug lösen könnten Ihre Linien in einzelnen Try-Catch-Blöcken zu wickeln. Nicht sicher, ob Sie meinten Sie nicht wollen manuell wickeln sie oder dass Sie wollten try-catch vermeiden vollständig .

Herumspielen mit diesem, habe ich versucht, jede Zeile Beschriftung und zurück von einem einzigen Haken, ohne viel Glück springen. Jedoch deckte Christopher die richtige Weg, um diese zu tun. Es gibt einige interessante zusätzliche Diskussion dies bei Dot Net Gedanken und unter Mike Stall .NET Blog .

EDIT: Natürlich. Die try-catch / switch-goto Lösung aufgeführt wird nicht wirklich kompilieren, da die try Etiketten sind out-of-scope in catch. Wer weiß, was so etwas wie dieses kompilieren machen fehlt?

Sie können dies automatisieren mit einem Compiler Vorverarbeitungsschritt oder vielleicht zerhacken Orion Adrian Antwort über die Ausnahme untersuchen und zu versuchen, die nächste Anweisung ist auch interessant zu setzen.)

Alles in allem scheint es wie eine interessante und lehrreiche Übung. Natürlich würden Sie, an welcher Stelle sich die Mühe zu entscheiden haben, On Error Resume Next schwerer wiegt als die Mühe zu simulieren, den Code zu beheben. : -)

Fangen Sie die Fehler in der UnhandledException Ereignis der Anwendung. Auf diese Weise können nicht behandelte execptions sogar als an den Absender angemeldet sein, und was auch immer andere Informationen der Entwickler wäre vernünftig.

Leider sind Sie wahrscheinlich kein Glück. On Error Resume Next eine Legacy-Option ist, die im Allgemeinen stark abgeraten, und ein äquivalentes meines Wissens nicht in C #.

Ich würde empfehlen, den Code in VB verlassen (Es klingt wie, dass die Quelle war, gegeben, spezifische Anfrage für OnError ResumeNext) und mit oder aus einem C # DLL oder EXE-Schnittstelle, die was auch immer neuer Code implementiert die Sie benötigen. Dann Refactoring Vorform der Code sicher sein, und wandeln diesen sicheren Code zu C #, um zu bewirken, wie Sie dies tun.

Sie die Enterprise Library Exception Handling-Komponente für eine Idee zur Integration aussehen könnten, wie Ausnahmen zu behandeln unhandled.

Wenn dies für ASP.Net-Anwendungen ist, gibt es eine Funktion in der Global.asax genannt „Application_Error“, die in den meisten Fällen mit katastrophalen Fehlern aufgerufen werden, in der Regel den anderen Fall zu sein.

Das Ignorieren alle Gründe, würden Sie wollen, dies zu vermeiden tun .......

Wenn es einfach ein Bedürfnis nach unten Anzahl der Linien zu halten, können Sie versuchen, etwas könnte wie:

int totalMethodCount = xxx;
for(int counter = 0; counter < totalMethodCount; counter++) {
    try {
        if (counter == 0) WidgetMaker.SetAlignment(57);
        if (counter == 1) contactForm["Title"] = txtTitle.Text;
        if (counter == 2) Casserole.Season(true, false);
        if (counter == 3) ((RecordKeeper)Session["CasseroleTracker"]).Seasoned = true;
    } catch (Exception ex) {
        // log here
    }
}

Allerdings würde Sie ein Auge auf den Geltungsbereich von Variablen halten müssen, wenn Sie versuchen, eine der Ergebnisse der Anrufe wieder zu verwenden.

Hilite jede Zeile, einer nach dem anderen, 'Surround mit' try / catch. Das vermeidet das Kopieren Einfügen von Ihnen erwähnten

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