我写了两个代码:
代码块1:
Stream dataStream;
using (var response = (HttpWebResponse)req.GetResponse())
{
dataStream = response.GetResponseStream();
}
//Open the stream using a StreamReader for easy access
using (var reader = new StreamReader(dataStream))
{
data = reader.ReadToEnd();
}
代码块2:
Stream dataStream;
using (var response = (HttpWebResponse)req.GetResponse())
{
dataStream = response.GetResponseStream();
//Open the stream using a StreamReader for easy access
using (var reader = new StreamReader(dataStream))
{
data = reader.ReadToEnd();
}
}
代码块1抛出错误:stream is not reachable
。
虽然在进步中,我认为两个代码将一样。
我在代码块2中添加了使用块到整个语句并且它正在工作。
但我很困惑为什么它在代码块1中抛出错误
答案 0 :(得分:5)
根据您指定的行为,似乎在处置HttpWebResponse
时,它会处理响应流。
答案 1 :(得分:2)
Rohit,第一个代码块抛出错误,因为一旦关闭using子句的大括号,该对象就被视为已丢弃。即,该对象留给GC收集。代码块1中的流的范围在第二个using语句之前已过期。
访问流的正确方法是第二个代码块。
答案 2 :(得分:1)
using
块可让您轻松,正确地使用一次性物品。因此,即使您在using
语句之外声明变量,using
语句中初始化的任何内容都将在using
块之后被处理。
通常,当您使用IDisposable对象时,您应该声明和 在using语句中实例化它。 using语句调用 以正确的方式处理对象上的方法,以及(当您使用它时) 如前所示)它也会导致对象本身超出范围 只要调用Dispose。在使用块中,对象是 只读,无法修改或重新分配。
答案 3 :(得分:1)
Stream
不是数据块,而是从“某处”读取数据的方法。
当您处理该响应时(通过退出使用块),您将断开与“某处”的连接。这意味着您无法再从该流中读取。
你的第二个例子让这个连接保持活着,直到你读完为止。
答案 4 :(得分:1)
using
语句确保当执行到达最后一个括号}
时,作用域对象在其上调用了Dispose函数,这意味着HttpWebResponse对象在第二个使用块中超出范围。 / p>
虽然您已在datastream
变量中保存了流,但尚未读取流本身,并且在您调用ReadToEnd()
时已完成此操作。由于HttpWebResponse超出范围或Disposed,您将收到您收到的异常。
答案 5 :(得分:0)
因为后编译(在IL中),您的代码将转换为以下
代码块:1
HttpWebResponse response=null;
Stream dataStream;
try
{
response = (HttpWebResponse) req.GetResponse();
dataStream = response.GetResponseStream();
}
finally
{
if(response!=null)
((IDisposable)response).Dispose();
}
StreamReader reader = null;
try
{
//DataStream is accessed AFTER response object is disposed
reader = new StreamReader(dataStream);
data = reader.ReadToEnd();
}
finally
{
if(reader!=null)
reader.Dispose();
}
代码块:2
HttpWebResponse response=null;
Stream dataStream;
try
{
response = (HttpWebResponse) req.GetResponse();
dataStream = response.GetResponseStream();
StreamReader reader = null;
try
{
//DataStream is accessed while response object is alive, and connected (not disposed)
reader = new StreamReader(dataStream);
data = reader.ReadToEnd();
}
finally
{
if (reader != null)
reader.Dispose();
}
}
finally
{
if(response!=null)
((IDisposable)response).Dispose();
}
正如您所看到的,在CodeBlock1中,您正在尝试访问尝试从Disposed(和断开连接的)HttWebResponse对象读取的流。