gpt4 book ai didi

c# - 来自 HttpWebRequest 生命周期范围的响应流

转载 作者:行者123 更新时间:2023-11-30 16:24:51 26 4
gpt4 key购买 nike

我有这个方法:

public Stream Load(string term)
{
var url = CreateSearchUrl(term);

var webRequest = (HttpWebRequest)WebRequest.Create(url);
var webResponse = webRequest.GetResponse();

return new GZipStream(webResponse.GetResponseStream(), CompressionMode.Decompress);
}

如您所见,我将流返回给调用者,但我不确定这是否安全,因为运行时会处理 WebRequest,从而使我返回的流无效。

我可以将其转换为字节数组并返回 MemoryStream 或什至使用 WebClient,但我只是不喜欢这个想法 =)。

谢谢!

最佳答案

没有一种简单的方法可以在不发生资源泄漏的情况下安全地返回 Stream。主要问题是处理 WebResponse:

public Stream Load(string term)
{
var url = CreateSearchUrl(term);

var webRequest = (HttpWebRequest)WebRequest.Create(url);
var webResponse = webRequest.GetResponse(); // whoops this doesn't get disposed!

return new GZipStream(webResponse.GetResponseStream(), CompressionMode.Decompress);
}

关闭 WebResponse 实际上比关闭响应流更重要,因为关闭 WebResponse 会隐式关闭响应流。

我知道让 WebResponse 与 Stream 一起处置的唯一方法是在 GZipStream 周围实现装饰器,在处置 WebResponse(以及 GZipStream)时处置它。尽管这可行,但代码量相当大:

class WebResponseDisposingStream : Stream
{
private readonly WebResponse response;
private readonly Stream stream;

public WebResponseDisposingStream(WebResponse response, Stream stream)
{
if (response == null)
throw new ArgumentNullException("response");
if (stream == null)
throw new ArgumentNullException("stream");

this.response = response;
this.stream = stream;
}

public override void Close()
{
this.response.Close();
this.stream.Close();
}

// override all the methods on stream and delegate the call to this.stream

public override void Flush() { this.stream.Flush(); } // example delegation for Flush()
// ... on and on for all the other members of Stream
}

也许更好的方法是继续传递样式,其中使用 Stream 的代码作为委托(delegate)传递:

public void Load(string term, Action<Stream> action)
{
var url = CreateSearchUrl(term);

var webRequest = (HttpWebRequest)WebRequest.Create(url);

using (var webResponse = webRequest.GetResponse())
using (var responseStream = webResponse.GetResponseStream())
using (var gzipStream = new GZipStream(responseStream, CompressionMode.Decompress))
{
action(gzipStream);
}
}

现在,调用者只需传递应该对 Stream 执行的操作。在下面,长度被打印到控制台:

Load("test", stream => Console.WriteLine("Length=={0}", stream.Length));

最后一点:如果您不知道,HTTP 内置了对压缩的支持。参见 Wikipedia更多细节。 HttpWebRequest 通过 AutomaticDecompression 内置了对 HTTP 压缩的支持。属性(property)。使用 HTTP 压缩基本上可以使压缩对您的代码透明,并且可以更好地与 HTTP 工具(浏览器、fiddler 等)配合使用。

关于c# - 来自 HttpWebRequest 生命周期范围的响应流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10442061/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com