2016-08-23 2 views
0

Ich habe einen Codewie Code-Analyse-Warnungen beheben

public String makeHttpGetRequest(String url) 
     { 
      try 
      { 
       string responce = string.Empty; 
       HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
       request.AutomaticDecompression = DecompressionMethods.GZip; 


       using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
       using (Stream stream = response.GetResponseStream()) 
       using (StreamReader reader = new StreamReader(stream)) 
       { 
        responce = reader.ReadToEnd(); 
       } 
       return responce; 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Internet Connection error" + e.Message); 
       return null; 
      } 
     } 

Und ich erhalte eine Warnung, wenn ich Code-Analyse in Visual Studio ausführen, die

CA2202 nicht entsorgen Sie Objekte mehrmals Objekt ‚stream 'kann in der Methode' InformationIO.makeHttpGetRequest (string) 'mehrfach entsorgt werden. Um zu vermeiden, Erzeugen eines System.ObjectDisposedException sollten Sie nicht mehr als einmal auf ein Objekt entsorgen rufen .: Linien: 244 InformationIO.cs 244

Linie 224 bezieht sich 13 hier die Schließbügel vor Rückkehr Antwort-Linie;

Wie kann ich diese Warnung beheben.

Antwort

0

Von MSDN

Das Streamreader-Objekt ruft Dispose() auf dem mitgelieferten Stream-Objekt wenn StreamReader.Dispose genannt wird.

Dies bedeutet, dass StreamReader das Dispose on Stream-Objekt aufruft und Ihre using-Anweisung dies auch tut. Alternative könnte sein:

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
    using (StreamReader reader = new StreamReader(response.GetResponseStream())) 
    { 
     responce = reader.ReadToEnd(); 
    } 
return responce; 
1

Diese beiden Linien verweisen auf die gleiche stream, und werden versuchen, es zweimal zu entsorgen:

using (Stream stream = response.GetResponseStream()) 
using (StreamReader reader = new StreamReader(stream)) 

Entfernen Sie den zweiten using Block (der drei Sie haben), da es nicht notwendig ist in diesem Fall.

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
{ 
    Stream stream = response.GetResponseStream()); 
    using (StreamReader reader = new StreamReader(stream)) 
    { 
     responce = reader.ReadToEnd(); 
    } 
} 

Wenn Sie wirklich sicher, dass der Strom sein wollen angeordnet ist, fügen Sie ein finally Block:

Stream stream = null; 
try 
{ 
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
    { 
     stream = response.GetResponseStream()); 
     using (StreamReader reader = new StreamReader(stream)) 
     { 
      responce = reader.ReadToEnd(); 
     } 
    } 
} 
finally 
{ 
    // check if stream is not null (although it should be), and dispose of it 
    if (stream != null) 
     stream.Dispose(); 
} 
0

Je tiefer hier Problem ist, dass das Design von StreamReader falsch ist; es sollte nie den zugrundeliegenden Strom entsorgen, weil es nicht besitzt es.

Das folgende Muster ist sehr verbreitet:

public class Foo: IDisposable 
{ 
    public Foo(Bar bar) {...} 
} 

public class Bar: IDisposable { ... } 

Wenn foo Entsorgung, sollte es nie für Sie bar automatisch entsorgen, weil es nicht bar nicht besitzt; bar ist ein Objekt, das vom Benutzer foo bereitgestellt wird; Es liegt daher in der Verantwortung des Benutzers, sich um bar zu kümmern.

Dies ist im Wesentlichen, was in Ihrem Code passiert; Sie kümmern sich korrekt um stream, aber StreamReader kümmert sich auch um etwas, das nicht wirklich sein Geschäft ist, stream für Sie zu entsorgen.

Also, um zu beenden: Ihr Code ist korrekt. Aufgrund eines Konstruktionsfehlers in StreamReader verursacht Ihr korrekter Code ein Problem, das behoben werden muss. Duplikate Anrufe zu Dispose().

Andere Antworten zeigen gute Möglichkeiten, das Problem zu beheben, also werde ich Code hier kopieren.