Stream.Dispose或stream = null?

Tem*_*ple 11 .net c#

我有一些类似的代码:

HttpWebRequest req;
HttpWebResponse response;
Stream receiveStream = null;
StreamReader readStream = null;
try
{
    req = (HttpWebRequest)WebRequest.Create("someUrl"));
    req.Credentials = CredentialCache.DefaultCredentials;

    req.Method = "GET";

    response = (HttpWebResponse)req.GetResponse();
    receiveStream = response.GetResponseStream();
    readStream = new StreamReader(receiveStream, Encoding.Default);

    return readStream.ReadToEnd();
}
catch
{
    return "Error";
}
finally 
{
    readStream = null;
    receiveStream = null;
    response = null;
    req = null;
}
Run Code Online (Sandbox Code Playgroud)

此代码是否应该具有readStream.Dispose()和responseStream.Dispose()而不是将它们都设置为null?

Jon*_*eet 28

将局部变量设置为null几乎总是错误的,除非您希望稍后实际使用该值.它不会更早地强制进行垃圾收集 - 如果您以后不打算从变量中读取,垃圾收集器可以忽略该引用(当不处于调试模式时).

但是,关闭流几乎总是正确的 - 理想情况下是using为了简单起见.

几乎总是错误的,有一个这样的裸"catch"块.你真的想要处理任何出错的事情,包括这样的事情OutOfMemoryException吗?

我会将您的代码重写为:

HttpWebRequest req = (HttpWebRequest) WebRequest.Create("someUrl"));
req.Credentials = CredentialCache.DefaultCredentials;
req.Method = "GET";

using (WebResponse response = req.GetResponse())
{
    using (StreamReader reader = new StreamReader(response.GetResponseStream(),
                                                  Encoding.Default))
    {
        return reader.ReadToEnd();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在如果出现问题,异常将传播给调用者.您可能希望捕获一些特定的异常,但使用可能是有效"正常"响应的值来表示错误通常不是一个好主意.

最后,你真的确定要Encoding.Default吗?这是本地计算机的默认编码- 您通常需要响应本身指示的编码.

  • 将局部变量设置为null有一个好处:它会提醒其他开发人员他们需要非常仔细地查看此人的代码. (5认同)

Jim*_*mmy 27

它应该有using[哪个电话Dispose()].


Hen*_*man 9

是的,Dispose()他们.

做更好的事情就更好了

using (HttpWebResponse response = (HttpWebResponse)req.GetResponse() )
using (Stream receiveStream = response.GetResponseStream() )
using (readStream = new StreamReader(receiveStream, Encoding.Default) )
{
   return readStream.ReadToEnd();
}
Run Code Online (Sandbox Code Playgroud)

using(x) {} 块将(由编译器)被重写
try {} finally {x.Dispose();}

请注意,WebRequest不是IDisposable.

另请注意,以下行与您的所有代码完成相同的操作:

using (var client = new System.Net.WebClient())
{
    client.Encoding = ...;
    client.Credentials = ...;
    return client.DownloadString("SomeUrl");
}
Run Code Online (Sandbox Code Playgroud)


Ari*_*yck 8

是.几乎任何实现Dispose()方法的东西都必须调用它的Dispose()方法.您可以使用'using'语句隐式调用它:

using(StreamReader stream = GetStream())
{
   stream.DoStuff();
}
Run Code Online (Sandbox Code Playgroud)