6 Stimmen

c# - ist es in Ordnung, ein "try/catch" innerhalb einer "using"-Anweisung für eine Web-Anfrage einzubetten? Ist mein Code korrekt?

Ist es in Ordnung, eine "try/catch"-Anweisung in eine "using"-Anweisung für eine Webanfrage einzubetten? Ist mein Code korrekt? Das heißt, meine Anforderungen sind:

  1. Möchten Sie die Anweisung "using" verwenden, um sicherzustellen, dass Ressourcen in jedem Fall für HttpWebResponse freigegeben werden

    • Aber noch wollen einige benutzerdefinierte Sachen zu tun, wenn es eine Ausnahme re HttpWebResponse und "Antwort = (HttpWebResponse)request.GetResponse();" im Besonderen.

Mein Quellcode:

        var result = new HttpHeaderInfo();
        HttpWebRequest request = null;
        HttpWebResponse response = null;
        using (response)
        {
            try
            {
                request = (HttpWebRequest)WebRequest.Create(uri);
                request.Method = "HEAD";
                request.KeepAlive = false;
                request.Timeout = Properties.Settings.Default.WebTimeoutDefault;

                response = (HttpWebResponse)request.GetResponse();
                result.LastModified = response.LastModified;
                result.ContentType = response.ContentType;
                result.StatusCode = response.StatusCode;
                result.ContentLength = response.ContentLength;
            }
            catch (Exception ex)
            {
                if (ex is InvalidOperationException ||
                    ex is ProtocolViolationException ||
                    ex is WebException)
                {
                    result.HttpError = ex;
                    result.LastModified = System.DateTime.MinValue;
                    result.ContentType = null;
                }
                else { throw; }
            }

        }

danke

11voto

Aaronaught Punkte 118136

Es ist in Ordnung, aber ein wenig überflüssig; im Allgemeinen könnte man die using Block, fügen Sie einen finally Block nach dem catch und rufen explizit Dispose enthalten, was die Verschachtelung in Ihrem Code reduzieren würde.

Was mich ein wenig stört, ist, dass Sie nicht wirklich zuordnen. response bis Sie innerhalb die using Block, und die expliziten Variablendeklarationen sind in diesem Zusammenhang unnötig und verwirrend. Ich würde es umschreiben als:

HttpHeaderInfo result;
try
{
    var request = (HttpWebRequest)WebRequest.Create(uri);
    request.Method = "HEAD";
    request.KeepAlive = false;
    request.Timeout = Properties.Settings.Default.WebTimeoutDefault;

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        result = new HttpHeaderInfo();
        result.LastModified = response.LastModified;
        result.ContentType = response.ContentType;
        result.StatusCode = response.StatusCode;
        result.ContentLength = response.ContentLength;
    }
}
catch (WebException ex)
{
    // etc.
}

Dies ist viel klarer als das ursprüngliche Formular. Beachten Sie auch, dass ich die WebException und nicht das generische System.Exception . Sie sollten bestimmte Ausnahmetypen abfangen, anstatt allgemeine Ausnahmen abzufangen und dann deren Typ zu überprüfen.

6voto

Jon Skeet Punkte 1325502

Andere haben darauf hingewiesen, dass dies ein potenziell Problem, aber ich möchte es als ein sehr eindeutig Das Problem ist, dass Ihre Aussage, die Sie verwenden, Ihnen im Moment überhaupt nichts nützt.

Wenn Sie eine using-Anweisung wie diese schreiben:

SomeType x = value1;
using (x)
{
    x = value2;
}

es ist value1 die am Ende des Blocks entsorgt wird, no value2 . In Ihrem Code, response ist bis innerhalb des Blocks null; die WebResponse die Sie am Ende haben werden no entsorgt werden.

Sie sollten diesbezüglich eine Warnung mit folgendem Inhalt erhalten:

Warnung CS0728: Möglicherweise falsche Zuordnung zu lokalem 'Antwort', die das Argument einer using- oder lock-Anweisung ist. Der Dispose-Aufruf oder Entsperren erfolgt mit dem ursprünglichen Wert des Local.

Diese Warnung ist wichtig - beachten Sie sie.

Abgesehen davon ist es durchaus sinnvoll, einen try/catch-Block in eine using-Anweisung zu setzen... aber in diesem Fall sollte es wahrscheinlich sein außerhalb die using-Anweisung, mit der Sie die Initialisierung der response zu einem geeigneten Zeitpunkt, so dass die Antwort immer entsorgt wird. Ich würde auch erwägen, mehrere Catch-Blöcke zu verwenden, die eine gemeinsame Methode aufrufen, anstatt "is" wiederholt zu verwenden.

1voto

Bruce Punkte 7824

Das ist völlig in Ordnung. Wenn Sie die Ausnahme behandeln und nicht wollen, dass sie sich weiter ausbreitet, ist das völlig in Ordnung, und verschachtelte try/catch/finally-Blöcke sind kein Problem. (Intern ist ein "using" wie dieses nur ein try/finally.)

UPDATE: Lesen Sie ein wenig näher, und ich denke, Sie wollen tatsächlich die Verwendung innerhalb der "Try"-Block - die Zeile, wo Sie tatsächlich ein Objekt in der "Antwort"-Variable ist, wo Sie wollen, dass die "Verwendung"-Block zu beginnen. Lässt es sich tatsächlich so kompilieren?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X